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. CLUSTER - 根据一个索引对某个表集簇

    SYNOPSIS CLUSTER indexname ON tablename CLUSTER tablename CLUSTER DESCRIPTION 描述 CLUSTER 指示PostgreSQ ...

  2. 说说C#中list与IList中的区别(转载)

    首先IList 泛型接口是 ICollection 泛型接口的子代,并且是所有泛型列表的基接口. 但是它仅仅是所有泛型类型的接口,并没有太多方法可以方便实用,如果仅仅是作为集合数据的承载体,确实,IL ...

  3. C#解析单层html的中的文本,然后拼接起来

    匹配单层html的小demo,应该能匹配大多数html字符串.多层(嵌套)html标签解析不出来.可能有小bug,我抛砖引玉下,哈哈. using System; using System.Colle ...

  4. JVM内存管理及垃圾回收机制

    一.JVM内存组成结构 JVM栈由堆.栈.本地方法栈.方法区等部分组成,结构图如下所示:  二.JVM内存回收 Sun的JVMGenerationalCollecting(垃圾回收)原理是这样的:把对 ...

  5. 采用Qt快速绘制多条曲线(折线),跟随鼠标动态显示线上点的值(基于Qt的开源绘图控件QCustomPlot进行二次开发)

    QCustomPlot是一个开源的基于Qt的第三方绘图库,能够绘制漂亮的2D图形. QCustomPlot的官方网址:https://www.qcustomplot.com/ 从官网下载QCustom ...

  6. 全国高校绿色计算大赛 预赛第一阶段(Python)

    第1关将字符串反转 #!/usr/bin/env python # -*- coding: utf-8 -*- class Task: def inversion(self, str): # **** ...

  7. [Usaco2009 Nov]lights(高斯消元)

    luogu 点灯游戏应该很多人都在小时候頽过吧 反正我直到现在也不会 很明显一个灯最多只需要点一次 然后高斯消元 解完肯定剩自由元(就是那些全是0的行) 然后这些都爆搜 由于剩下的自由元不会太多 所以 ...

  8. 新进Linux菜鸟,请多多关照

    早早知晓Linux的大名,一直未研究学习,近来看了kernel一些源代码,在网上搜过很多基础的知识.感觉这个Linux的世界很广大,值得好好深入学习.初生婴儿,呱呱落地,必先躺若干日后能坐,在学爬,进 ...

  9. Flask(1):基本示例、配置文件、路由、请求和响应、模板渲染

    Flask的特点: - pip install flask - 短小精悍.可扩展性强的 web框架 注意:上下文管理机制 - 依赖 wsgi:werkzeug Flask的简单示例: from fla ...

  10. 前端开发:JQuery(1)

    JQuery DOM文档加载的步骤: 1. 解析HTML结构: 2. 加载外部脚本和样式: 3. 解析并执行脚本代码: 4. DOM树构建完成: 5. 加载图片等外部文件: 6. 页面加载完成: JS ...