原文链接: 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. jquery.validate动态更改校验规则

    有时候表单中有多个字段是相互关联的,以下遇到的就是证件类型和证件号码的关联,在下拉框中选择不同的证件类型,证件号码的值的格式都是不同的,这就需要动态的改变校验规则. 点击(此处)折叠或打开 <! ...

  2. poj2709

    模拟题,在合成灰色的时候,每次取当前剩余最多的三种颜色,各取1mL合成.然后重新看剩余最多的是哪三个. #include <cstdio> #include <cstdlib> ...

  3. list 复制

    a=[1,2,3] b=a #b值改变,a也会改变 b[0]=90 print(a) [90,2,3] b=list(a) #这样修改b,a的值就不会改变

  4. 【转】ElasticSearch之定时删除数据

    有的时候我们在使用ES时,由于资源有限或业务需求,我们只想保存最近一段时间的数据,所以有如下脚本可以定时删除数据 delete_es_by_day.sh #!/bin/sh # example: in ...

  5. Ueditor结合七牛云存储上传图片、附件和图片在线管理的实现和最新更新

    最新下载地址: https://github.com/widuu/qiniu_ueditor_1.4.3 Ueditor七牛云存储版本 注意事项 老版本请查看 : https://github.com ...

  6. hdu 5007 水题 (2014西安网赛A题)

    题意:出现Apple.iPod.iPhone.iPad时输出MAI MAI MAI!,出现Sony,输出SONY DAFA IS GOOD! Sample InputApple bananaiPad ...

  7. 【LOJ】#2265. 「CTSC2017」最长上升子序列

    题解 点了一个新技能叫杨表(事实上集训的时候听过,但是一直不会 这道题就是让我们找到k个不上升子序列,要求长度加和最大 我们用杨表去维护,但是由于杨表的行数可能是n的,复杂度会炸 我们只维护前\(\s ...

  8. 【Ubuntu】Ubuntu设置和查看环境变量

    [Ubuntu]Ubuntu设置和查看环境变量    转载 https://blog.csdn.net/White_Idiot/article/details/78253004 1. 查看环境变量 查 ...

  9. Python3 CNN中卷积和池化的实现--限制为二维输入

    # -*- coding: utf-8 -*- """ Created on Wed Jan 31 14:10:03 2018 @author: markli " ...

  10. 自己的reset.css

    复制.粘贴 /* http://www.cnblogs.com/ele-cat Reset Stylesheet v1.0.1 2018-05-08 Author: Ele-cat - http:// ...