原文链接: 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. ASP.NET应用技巧:非托管COM组件的使用

    众所周知,asp.net是基于通用语言运行库创建的,也就是所谓的托管执行环境.生成的代码称为托管代码.编译器能够从源代码的描述中产生元数据信息,而运行库又从元数据中获得托管代码的信息.而我们编写的组件 ...

  2. nginx前后端分离路由配置

    参考链接: https://blog.csdn.net/qq_30021219/article/details/80901199

  3. 2018-11-1 NOIP 模拟赛解题报告

    T1 Domino 多米诺骨牌 题目大意 给你N个骨牌,上下各有一个数,要使上面一排的和为偶数,同时下面一排的和也为偶数,最多要翻转多少次?如果无法达成那么输出-1. 解法 水题秒切 根据数的奇偶性质 ...

  4. ****timeago.js插件:jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例

    前端 时间个性化 插件 jquery.timeago.js 关键词 : 时间格式化 刚刚 N分钟前 N小时前 N天前 N月前 N年前 MM-dd hh:mm  或者  yyyy-MM-dd 前端: & ...

  5. 【PAT】1032 Sharing (25)(25 分)

    1032 Sharing (25)(25 分) To store English words, one method is to use linked lists and store a word l ...

  6. 2018年东北农业大学春季校赛 C-wyh的商机

    一天,你们wyh学长和你们zhl学长玩一个游戏,这个游戏规则是这样的 给你n个城市,保证这n个城市之间都只有一条道路可以到达. 有一件物品,在所有城市中都是一样的,但是由于各个城市的经济发展不同,导致 ...

  7. 007 @CookieValue绑定请求中的cookie

    1.介绍 2.使用的cookie 3.index.jsp <%@ page language="java" contentType="text/html; char ...

  8. 常用的服务发现对比(Consul、zookeeper、etcd、eureka)

    这里就平时经常用到的服务发现的产品进行下特性的对比,首先看下结论:   Feature Consul Zookeeper Etcd Eureka 服务健康检查  服务状态,内存,硬盘等  (弱)长连接 ...

  9. node.js之nodemon 代码热更新 修改代码后服务器自动重启

    1.安装nodemon: npm install -g nodemon //全局安装 npm install nodemon --save //局部安装 2.在项目根目录下创建 nodemon.jso ...

  10. 深刻理解this的指向和var 定义的变量的问题

    一般来说,在编程语言里我们常见的变量作用域就是词法作用域与动态作用域(Dynamic Scope),绝大部分的编程语言都是使用的词法作用域.词法作用域注重的是所谓的Write-Time,即编程时的上下 ...