C#编程(五十四)----------Lookup类和有序字典
原文链接: 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类和有序字典的更多相关文章
- C#高级编程五十四天----Lookup类和有序字典
Lookup类 Dictionary<Tkey,TValue>仅仅为每一个键支持一个值.新类Lookup<Tkey,TValue>是.NET3.5中新增的,它类似与Dictio ...
- 第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection)
第三百五十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection) Scrapy提供了方便的收集数据的机制.数据以key/value方式存储,值大多是计数 ...
- 孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档
孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数据库 ...
- “全栈2019”Java第五十四章:多态详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- abp(net core)+easyui+efcore实现仓储管理系统——出库管理之五(五十四)
abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统--ABP总体介绍(一) abp(net core)+ ...
- 五十四、linux 编程——TCP 编程模型
54.1 编程模型介绍 54.1.1 TCP 客户端服务器编程模型 客户端调用序列 调用 socket 函数创建套接字 调用 connect 连接服务器端 调用 I/O 函数(read/write) ...
- Java开发笔记(五十四)内部类和嵌套类
通常情况下,一个Java代码文件只定义一个类,即使两个类是父类与子类的关系,也要把它们拆成两个代码文件分别定义.可是有些事物相互之间密切联系,又不同于父子类的继承关系,比如一棵树会开很多花朵,这些花儿 ...
- 五十四 网络编程 TCP编程
Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可. 客户端 大多数连接都是可靠 ...
随机推荐
- 001_软件waf
一.优秀的软件waf开源软件 <1>openwaf介绍 http://www.oschina.net/p/openwaf http://git.oschina.net/miracleqi ...
- Java动态性之--反射机制
1. 动态语言 程序运行时,可以改变结构或变量类型.典型的语言: Python.ruby.javascript等 如下javascript代码 function test(){ var s = &qu ...
- bzoj 1150
思路:写的时候感觉是贪心但是没有什么思路... 看了题解,原来有一个选了能反悔的贪心思路, 如果最优那么每个城市只能和旁边的相邻 城市连边,所以问题变成了由n个数,不能取相邻的两个数,取k个最小是多少 ...
- Win10解决无法访问其他机器共享的问题
Win10解决无法访问其他机器共享的问题 你不能访问此共享文件夹,因为你组织的安全策略阻止未经身份验证的来宾访问.这些策略可帮助保护你的电脑免受网络上不安全设备或恶意设备的威胁. 管理员身份执 ...
- win7下再装Ubuntu双系统
一.UltraISO制作U盘启动盘 1.1打开 UltraISO,单机“文件”,选择“打开”. 1.2然后单击“启动”,选择“写入硬盘映像”. 二.装Ubuntu 前面省略,直接到安装类型(我的安装好 ...
- q.size()
在队列中,q.empty()比q.size()要慢,如果可能就用q.size(); 比如spfa的 while(q.size()>0) better than while(!q.empty())
- 大数据小视角4:小议Lambda 与 Kappa 架构,不可变数据的计算探索
这个系列文章之前因为私事荒废了很久,继续更新--之前与老大谈论架构时,老大和我聊了聊分布式数据处理之中的Lambda结构,之前在<Designing Data-Intensive Applica ...
- Vue之双向绑定原理动手记
Vue.js的核心功能有两个:一是响应式的数据绑定系统,二是组件系统.本文是通过学习他人的文章,从而理解了双向绑定原理,从而在自己理解的基础上,自己动手实现数据的双向绑定. 目前几种主流的mvc(vm ...
- Redis集群主从复制(一主两从)搭建配置教程【Windows环境】
如何学会在合适的场景使用合适的技术方案,这值得思考. 由于本地环境的使用,所以搭建一个本地的Redis集群,本篇讲解Redis主从复制集群的搭建,使用的平台是Windows,搭建的思路和Linux上基 ...
- Android通知栏沉浸式/透明化完整解决方案
转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6640649.html 参考文献:https://github.com/ljgsonx/adaptiveSt ...