原文链接: http://blog.csdn.net/shanyongxu/article/details/47071607

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类和有序字典的更多相关文章

  1. C#高级编程五十四天----Lookup类和有序字典

    Lookup类 Dictionary<Tkey,TValue>仅仅为每一个键支持一个值.新类Lookup<Tkey,TValue>是.NET3.5中新增的,它类似与Dictio ...

  2. 第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection)

    第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection) Scrapy提供了方便的收集数据的机制.数据以key/value方式存储,值大多是计数 ...

  3. 孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档

    孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数据库 ...

  4. “全栈2019”Java第五十四章:多态详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  6. abp(net core)+easyui+efcore实现仓储管理系统——出库管理之五(五十四)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统--ABP总体介绍(一) abp(net core)+ ...

  7. 五十四、linux 编程——TCP 编程模型

    54.1 编程模型介绍 54.1.1 TCP 客户端服务器编程模型 客户端调用序列 调用 socket 函数创建套接字 调用 connect 连接服务器端 调用 I/O 函数(read/write) ...

  8. Java开发笔记(五十四)内部类和嵌套类

    通常情况下,一个Java代码文件只定义一个类,即使两个类是父类与子类的关系,也要把它们拆成两个代码文件分别定义.可是有些事物相互之间密切联系,又不同于父子类的继承关系,比如一棵树会开很多花朵,这些花儿 ...

  9. 五十四 网络编程 TCP编程

    Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可. 客户端 大多数连接都是可靠 ...

随机推荐

  1. Gentoo rc-update service ‘net.eth0′ does not exist

    最近迷上了Gentoo,并相信以后也会把更多的精力放在Gentoo上,不过Gentoo的安装的过程的确让很多人却步. 本文只提到添加net.eth0到默认的运行级别时一个很小的报错解决. # nano ...

  2. thymeleaf : EL1050E The arguments (...) for the constructor call are missing

    <a href="list.html" th:href="${#strings.replace(new.href,'{page}',1)}" >MO ...

  3. 使用OpenSSL自建CA + Nginx配置HTTPS

    Ubuntu 16.04(ECS),OpenSSL 1.0.2g  1 Mar 2016,Nginx 1.10.3 (Ubuntu), 浏览器:Chrome 67,Firefox 61,Edge 40 ...

  4. C/C++的64位整型

    在C/C++中,64为整型一直是一种没有确定规范的数据类型.现今主流的编译器中,对64为整型的支持也是标准不一,形态各异.一般来说,64位整型的定义方式有long long和__int64两种(VC还 ...

  5. 193 Valid Phone Numbers

    Given a text file file.txt that contains list of phone numbers (one per line), write a one liner bas ...

  6. Qt QByteArray或者Char转十六进制 QString

    1.QByteArray转十六进制 QByteArray buff = sp->readAll(); qDebug() << buff.toHex() << " ...

  7. 【LOJ】#2075. 「JSOI2016」位运算

    题解 压的状态是一个二进制位,我们规定1到n的数字互不相同是从小到大,二进制位记录的是每一位和后一个数是否相等,第n位记录第n个数和原串是否相等,处理出50个转移矩阵然后相乘,再快速幂即可 代码 #i ...

  8. redis 相关知识点

    (1)什么是redis? Redis 是一个基于内存的高性能key-value数据库. (有空再补充,有理解错误或不足欢迎指正) (2)Reids的特点 Redis本质上是一个Key-Value类型的 ...

  9. 使用Vmware安装linux且配置终端可以连接虚拟机总结

    首先是下载一个linux镜像,我下载的是:ubuntu-16.04.2-desktop-amd64.iso 1.使用vmware安装linux,都使用默认的配置就行了,最多改一下主机名什么的,密码最好 ...

  10. 七夕情人节表白-纯JS实现3D心形+图片旋转

    七夕情人节就快到了,这里献上纯js表白神器-心里都是你,预览: 技术点:css-3d.js-随机色.js-transform 1.html: <div class="heart&quo ...