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类和有序字典

    原文链接: http://blog.csdn.net/shanyongxu/article/details/47071607 Lookup类 Dictionary<Tkey,TValue> ...

  2. 【读书笔记】C#高级编程 第二十四章 文件和注册表操作

    (一)文件和注册表 对于文件系统操作,相关的类几乎都在System.IO名称空间中,而注册表操作由System.Win32名称空间中的类来处理. (二)管理文件系统 System.MarshalByR ...

  3. 【读书笔记】C#高级编程 第十四章 内存管理和指针

    (一)后台内存管理 1.值数据类型 Windows使用一个虚拟寻址系统,该系统把程序可用的内存地址映射到硬件内存中的实际地址,该任务由Windows在后台管理(32位每个进程可使用4GB虚拟内存,64 ...

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

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

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

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

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

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

  7. 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘

    孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...

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

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

  9. C++面向对象高级编程(五)类与类之间的关系

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 本节主要介绍一下类与类之间的关系,也就是面向对象编程先介绍两个术语 Object Oriented Programming   OOP面向对象编 ...

随机推荐

  1. 开放API接口

    [开放API]——知乎.博客园等开放API接口(更新ing)   Cnodejs.org: https://cnodejs.org/api/ 和风天气: http://docs.heweather.c ...

  2. 使用VS Code调试Flutter(检查用户页面)

    官方提供的是Flutter Widget Inspector,详见https://flutterchina.club/inspector/ 我用的是另外一种好用的调试工具 Dart DevTools ...

  3. 第一节、ES6的开发环境搭建

    https://blog.csdn.net/zls986992484/article/details/70819462 下面这个不好使 https://blog.csdn.net/gao5311624 ...

  4. element-ui iview-admin 都是基于vue的ui框架

    element-ui iview-admin 都是基于vue的ui框架

  5. CAD参数绘制半径标注(网页版)

    主要用到函数说明: _DMxDrawX::DrawDimRadial 绘制一个半径标注.详细说明如下: 参数 说明 DOUBLE dCenterX 被标注的曲线的中点X值 DOUBLE dCenter ...

  6. 删数问题(Noip1994)

    1321:[例6.3]删数问题(Noip1994) 时间限制: 1000 ms         内存限制: 65536 KB提交数: 5127     通过数: 1595 [题目描述] 输入一个高精度 ...

  7. CPU怎么计算1+1----CPU计算的电路基础

    从<十进制和二进制的运算---我所理解到的人类的运算的本质>这里我们知道,人类进行运算的本质是查表,并且我们存储的表是有限的.那么计算机是怎进行四则运算的呢,也是查表吗,肯定不是,今天,我 ...

  8. JavaSE-19 IO

    学习要点 File类操作文件和目录的属性 字节流读写文件 字符流读写文件 字节流读写二进制文件 文件操作 1  文件的定义 文件可认为是相关记录或放在一起的数据的集合.文件一般保存在硬盘.U盘.光盘. ...

  9. 解决 python No migrations to apply 无法生成表

    第一步: 删除该app名字下的migrations文件. 第二步: 进入数据库,找到django_migrations的表,删除该app名字的所有记录. delete from django_migr ...

  10. python3.x Day5 subprocess模块!!

    subprocess模块: # subprocess用来替换多个旧模块和函数 os.system os.spawn* os.popen* popen2.* commands.* subprocess简 ...