C#高级编程五十四天----Lookup类和有序字典
Lookup类
Dictionary<Tkey,TValue>仅仅为每一个键支持一个值.新类Lookup<Tkey,TValue>是.NET3.5中新增的,它类似与Dictionary<Tkey,TElement>,但把键映射带一个值集上.这个类在程序及System.Core中实现,用System,Linq命名空间定义.
Lookup<Tkey,TElement>的方法和属性例如以下表:
属性名或者方法名 |
说明 |
Count |
属性Count返回集合中的元素个数 |
Item |
使用索引器能够依据键訪问特定的元素.由于同一个键能够相应多个值,所以这个属性返回全部值的枚举 |
Contain() |
方法Contains()依据使用用Key參数传送元素,返回一个布尔值 |
ApplyResultSelector() |
ApplyResultSelector(0依据传送给它的转换函数,转换每一项,返回一个集合 |
Loopup<TKey,TElement>不能像一般的字典那样创建,而必须调用方法ToLookup(),它返回一个Lookup<TKey,TElement>对象.方法ToLookup()是一个扩展方法,能够用于实现了IEnumerable<T>的全部类.
当一个Key要求相应多个value情况ToLookup方法很实用,ToLookup返回一种特殊的数据结构,类似SQL中的group,能够把集合分组而且能够用索引訪问这些元素,案例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lookup类
{
class Program
{
static void Main(string[] args)
{
//创建一个string类型的数组
string[] array = { "cat","dog","horse"};
//生成查找结构
var lookup = array.ToLookup(item => item.Length);
//枚举字符长度3的串
foreach (var item in lookup[3])
{
Console.WriteLine("3 = "+item);
}
//枚举字符长度5的串
foreach (var item in lookup[5])
{
Console.WriteLine("5 = " + item);
}
//枚举分组
foreach (var grouping in lookup)
{
Console.WriteLine("Grouping : ");
foreach (var item in grouping)
{
Console.WriteLine(item);
}
}
Console.ReadKey();
}
}
}
上面的案例是通过数组元素的字符串长度为Key分组,也就是字符长度同样的元素的Key是一样的,索引下标也是一样.比方以通过lookup[3]訪问,而horse要用lookup[5]来訪问.
有序字典
SortedDictionary<TKey,TValue>类是一个二叉搜索树,当中的元素依据键来排序.该键类型必须实现IComparable<TKey>接口.假设键的类型不能排序,则还能够创建一个实现了IComparer<TKey>接口的比較器,将比較器用作有序字典的构造函数的一个參数.
SortedDictionary<TKey,TValue>类和SortedList<TKey,TValue>类的功能类似.但由于SortedList<TKey,TValue>实现为一个基于数组的列表,而SortedDictionary<TKey,TValye>类实现为一个字典,所以他们有不同的特征:
1.SortedList<Tkey,TValue>类使用的内存比SortedDictionary<TKey,TValue>类少
2.SortedDictionary<TKey,TValue>类的元素插入和删除速度比較快
3.在用已排好序的数据填充集合时,若不须要改动容量,SortedList<TKey,TValue>类就比較快.
案例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 有序字典
{
class Program
{
static void Main(string[] args)
{
//SortedList<TKey,TValue>使用的内存少
//SortedDictionary<TKey,TValue>元素插入和删除速度快
//键要实现IComparable<in T>接口
SortedDictionary<EmployeeID, Person> sd = new SortedDictionary<EmployeeID, Person>();
sd.Add(new EmployeeID(3),new Person("中国", "张飞", 40));
sd.Add(new EmployeeID(20), new Person("中国", "关羽", 43));
sd.Add(new EmployeeID(4), new Person("中国", "刘备", 45));
sd.Add(new EmployeeID(5), new Person("中国", "诸葛亮", 24));
sd.Add(new EmployeeID(1), new Person("美国", "豪威尔", 40));
sd.Add(new EmployeeID(0),new Person("美国", "奥巴马", 40));
sd.Add(new EmployeeID(210), new Person("朝鲜", "金三胖", 40));
sd.Add(new EmployeeID(80), new Person("印度", "印度阿三", 40));
foreach (var item in sd)
{
Console.WriteLine(item.Key.ID+","+item.Value.Name);//键。正序排序
}
Console.ReadKey();
}
}
public class EmployeeID : IComparable<EmployeeID>
{
public int ID { get; private set; }
public EmployeeID(int id)
{
this.ID = id;
}
public int CompareTo(EmployeeID other)
{
return ID.CompareTo(other.ID);
}
}
public class Person
{
public string Country { get; private set; }
public string Name { get; private set; }
public int Age { get; private set; }
public Person(string country, string name, int age)
{
this.Country = country;
this.Name = name;
this.Age = age;
}
}
}
注意:SortedList类使用的内存比SortedDictionary类少,但SortedDictionary类在插入和删除未排序的数据时比較快.
具体分析SOrtedList和SortedDictionary类的不同,SortedList内部用数组保存,仅仅能算是有序线性表,而SortedSictionary的内部结构是红黑树(这是一种数据结构,不懂得自己去百度).
SortedDictionary内部结构是红黑树,红黑树的平衡二叉树的一种,SortedList是有序线性表,内部结构是Array,运用了二分查找法提高效率.从两者查找,插入,删除操作的时间复杂度来看,都为O(LogN),分辨不出优劣,但内部结构的不同导致了实际操作的性能差异.
SortedList和SortedDictionary性能比較----插入
因为SortedList用数组保存,每次进行插入操作时,首先用二分查找发找到对应的位置,得到位置以后,SortedList会把该位置以后的值依次往后移动一个位置,空出当前位,再把值插入,这个过程用到了Array.Copy方法,而调用该方法是比較损耗性能的,代码例如以下:
private void Insert(int index,TKey key,TValue value)
{
...
if(index<this._size)
{
Array.Copy(this.keys.index,this.keys,index+1,this._size-index);
Array.Copy(this.values,index,this.values,index+1,this._size-index);
}
...
}
SortedDictionary在加入操作时,仅仅会依据红黑树的特性,旋转节点,保持平衡,并没有对Array.Copy的调用.
測试代码:循环一个int型,容量为100000的随机数组,分别用SortedList和SortedDictionary加入.
结论:在大量加入操作的情况下,SortedDictionary性能优于DortedList.
SortedList和SortedDictionary性能比較----查询
两者的查询操作中,事件复杂度都为O(LogN),且源代码中也没有额外的操作造成性能损失.
经过測试得出:两者在循环10W次的情况下,只相差几十毫秒,能够看出两者的查询操作性能相差不大.
SortedList和SortedDictionary性能比較----删除
从加入操作的案例能够看出,因为SortedList内部使用数组进行存储数据,而数组本身的局限性使得SortedList大部分的加入操作都要滴啊用Array.Copy方法,从而导致了性能的损失,这样的情况相同存在于删除操作中.所以得出了:在大量删除操作的情况下是,SortedDictionary的性能优于SortedList.
总结:SortedDictionary内部用红黑树存储数据,SortedList用数组存储数据,两者的查询效率几乎相同,但因为数组本身的限制,在大量加入删除操作的情况下,SortedDictionary的性能优于SortedList.
C#高级编程五十四天----Lookup类和有序字典的更多相关文章
- C#编程(五十四)----------Lookup类和有序字典
原文链接: http://blog.csdn.net/shanyongxu/article/details/47071607 Lookup类 Dictionary<Tkey,TValue> ...
- 【读书笔记】C#高级编程 第二十四章 文件和注册表操作
(一)文件和注册表 对于文件系统操作,相关的类几乎都在System.IO名称空间中,而注册表操作由System.Win32名称空间中的类来处理. (二)管理文件系统 System.MarshalByR ...
- 【读书笔记】C#高级编程 第十四章 内存管理和指针
(一)后台内存管理 1.值数据类型 Windows使用一个虚拟寻址系统,该系统把程序可用的内存地址映射到硬件内存中的实际地址,该任务由Windows在后台管理(32位每个进程可使用4GB虚拟内存,64 ...
- 孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档
孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数据库 ...
- 第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection)
第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection) Scrapy提供了方便的收集数据的机制.数据以key/value方式存储,值大多是计数 ...
- “全栈2019”Java第五十四章:多态详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘
孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...
- 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- C++面向对象高级编程(五)类与类之间的关系
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 本节主要介绍一下类与类之间的关系,也就是面向对象编程先介绍两个术语 Object Oriented Programming OOP面向对象编 ...
随机推荐
- CLUSTER - 根据一个索引对某个表集簇
SYNOPSIS CLUSTER indexname ON tablename CLUSTER tablename CLUSTER DESCRIPTION 描述 CLUSTER 指示PostgreSQ ...
- 说说C#中list与IList中的区别(转载)
首先IList 泛型接口是 ICollection 泛型接口的子代,并且是所有泛型列表的基接口. 但是它仅仅是所有泛型类型的接口,并没有太多方法可以方便实用,如果仅仅是作为集合数据的承载体,确实,IL ...
- C#解析单层html的中的文本,然后拼接起来
匹配单层html的小demo,应该能匹配大多数html字符串.多层(嵌套)html标签解析不出来.可能有小bug,我抛砖引玉下,哈哈. using System; using System.Colle ...
- JVM内存管理及垃圾回收机制
一.JVM内存组成结构 JVM栈由堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 二.JVM内存回收 Sun的JVMGenerationalCollecting(垃圾回收)原理是这样的:把对 ...
- 采用Qt快速绘制多条曲线(折线),跟随鼠标动态显示线上点的值(基于Qt的开源绘图控件QCustomPlot进行二次开发)
QCustomPlot是一个开源的基于Qt的第三方绘图库,能够绘制漂亮的2D图形. QCustomPlot的官方网址:https://www.qcustomplot.com/ 从官网下载QCustom ...
- 全国高校绿色计算大赛 预赛第一阶段(Python)
第1关将字符串反转 #!/usr/bin/env python # -*- coding: utf-8 -*- class Task: def inversion(self, str): # **** ...
- [Usaco2009 Nov]lights(高斯消元)
luogu 点灯游戏应该很多人都在小时候頽过吧 反正我直到现在也不会 很明显一个灯最多只需要点一次 然后高斯消元 解完肯定剩自由元(就是那些全是0的行) 然后这些都爆搜 由于剩下的自由元不会太多 所以 ...
- 新进Linux菜鸟,请多多关照
早早知晓Linux的大名,一直未研究学习,近来看了kernel一些源代码,在网上搜过很多基础的知识.感觉这个Linux的世界很广大,值得好好深入学习.初生婴儿,呱呱落地,必先躺若干日后能坐,在学爬,进 ...
- Flask(1):基本示例、配置文件、路由、请求和响应、模板渲染
Flask的特点: - pip install flask - 短小精悍.可扩展性强的 web框架 注意:上下文管理机制 - 依赖 wsgi:werkzeug Flask的简单示例: from fla ...
- 前端开发:JQuery(1)
JQuery DOM文档加载的步骤: 1. 解析HTML结构: 2. 加载外部脚本和样式: 3. 解析并执行脚本代码: 4. DOM树构建完成: 5. 加载图片等外部文件: 6. 页面加载完成: JS ...