.Net 中HashTable,HashMap 和 Dictionary<key,value> 和List<T>和DataTable的比较
参考资料
http://www.cnblogs.com/MichaelYin/archive/2011/02/14/1954724.html
http://www.cnblogs.com/lori/archive/2011/08/09/2132380.html
http://www.coding123.net/article/20120419/DataTable-IList-compare.aspx
首先:
(ling)在.Net 模仿java 的过程中 抛弃了 HashMap ,所以以后再去面试.Net的时候当别人问你HashTable 和HashMap 的区别的时候,请告诉他,C#.Net 中 没有HashMap
好接下来进入正题
.Net 中HashTable 和 Dictionary<key,value> 和List<T>的比较(不要问我怎么和题目不一样),本文只比较两种数据类型在使用时 功能相近的情况,差别太大的 则不比较。
先来比较
(yi)HashTable 和Dic
数据结构
Hashtable和Dictionary从数据结构上来说都属于Hashtable(哈希表),都是对关键字(键值)进行散列操作,将关键字散列到Hashtable的某一个槽位中去,不同的是处理碰撞的方法。散列函数有可能将不同的关键字散列到Hashtable中的同一个槽中去,这个时候我们称发生了碰撞,为了将数据插入进去,我们需要另外的方法来解决这个问题。


采用链表法的是Dic 而采用开放寻址法(open addressing)-中 双重散列的方法的是 HashTable
至于这两种数据结构的使用方法 请自行阅读算法导论 或者参照网上博客
但从底层的数据结构可以发现
如果增删的动作很多的话 推荐使用Dic 因为解决碰撞的方式 是List.Add
如果改动的动作很少 查询的动作很多的话 则推荐 使用HashTable 因为映射查找之后 只需要跳跃查找到 碰撞后移动数据即可,另外当增加数据太多时,开放寻址的扩容很耗费性能(请阅读<算法导论>)
Dic 和HashTable使用比较
1:单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分.
2:多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized() 方法可以获得完全线程安全的类型. 而 Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减.
3:Dictionary 有按插入顺序排列数据的特性 (注: 但当调用 Remove() 删除过节点后顺序被打乱), 因此在需要体现顺序的情境中使用 Dictionary 能获得一定方便. //Dic遍历时 会采用插入时的遍历,而hashTable 采用遍历时 则是打乱的
Hashtable 类和 Dictionary<TKey, TValue> 泛型类实现 IDictionary 接口
Dictionary<TKey, TValue> 泛型类还实现 IDictionary<TKey, TValue>泛型接口。
因此,这些集合中的每个元素都是一个键/值对。
Dictionary<TKey, TValue> 类与 Hashtable 类的功能相同
对于值类型,特定类型(不包括 Object)的 Dictionary<TKey, TValue> 的性能优于 Hashtable,这是因为 Hashtable 的元素属于 Object 类型,所以在存储或检索值类型时通常发生装箱和取消装箱操作。
(er)Dic 和 List<T>
关于数据结构:
在前边的比较已经介绍了Dic 那么 List <T> 的数据结构是什么样子的:
List<T>是 ArrayList 的泛型等效类(继承了泛型接口)
堆中的样子是这样的

我们为了讨论遍历时Dictionary和List的效率,有个高人写了个代码,这是载图

很明显,LIST效率要好的多。
问题剖析
同样是集合,为什么性能会有这样的差距。我们要从存储结构和操作系统的原理谈起。
首先我们清楚List<T>是对数组做了一层包装,我们在数据结构上称之为线性表,而线性表的概念是,在内存中的连续区域,除了首节点和尾节点外,每个节点都有着其唯一的前驱结点和后续节点。我们在这里关注的是连续这个概念。
而HashTable或者Dictionary,他是根据Key而根据Hash算法分析产生的内存地址,因此在宏观上是不连续的,虽然微软对其算法也进行了很大的优化。
由于这样的不连续,在遍历时,Dictionary必然会产生大量的内存换页操作,而List只需要进行最少的内存换页即可,这就是List和Dictionary在遍历时效率差异的根本原因。
所以根据value 的查找 dic 的效率是高于 List 的 但是遍历的话 则Dic 要差点。这就好比你要摘抄书里边的所有文字 是根据目录 查一个找一篇文章 快,还是直接从正文开始 从头到尾快遍历快一样。单独的找某一篇知道题目(key)的文章 当然是从目录快了
再谈Dictionary
也许很多人说,既然Dictionary如此强大,那么我们为什么不用Dictionary来代替一切集合呢?
在这里我们除了刚才的遍历问题,还要提到Dictionary的存储空间问题,在Dictionary中,除了要存储我们实际需要的Value外,还需要一个辅助变量Key,这就造成了内存空间的双重浪费。
而且在尾部插入时,List只需要在其原有的地址基础上向后延续存储即可,而Dictionary却需要经过复杂的Hash计算,这也是性能损耗的地方。
List<T>和 DataTable
DataTable,IList性能比较
1)二进制序列化的情况
从测试结果可以看出,IList<T>序列化的文件大小比DataTable小得多,这意味着在数据传输中带宽占用小很多,所以在设计Remoting接口时尽量使用IList<T>作返回值。
2)XML序列化的情况
从测试结果可以看出,IList<T>序列化后的文件比同样比DataTable小,但差距已经没有二进制序列化那么明显了。而且IList<T>的二进制序列化和XML序列化相差很大,所以remoteing中建议使用二进制序列化。
3)操作性比较
DataTable有支持数据的提交、回滚、查询等强大的方法,但访问单元格内容的时候不方便,还要类型转换。
IList<T>则访问项的属性比较方便,有属性自动提示,不用类型转换,有LINQ的协助也能实现强大的查询。
.Net 中HashTable,HashMap 和 Dictionary<key,value> 和List<T>和DataTable的比较的更多相关文章
- Hashtable,HashMap,Dictionary的区别
Hashtable和HashMap的区别:1.Hashtable是基于Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现,c#中无HashMap2.Hashtable ...
- 沉淀再出发:java中的HashMap、ConcurrentHashMap和Hashtable的认识
沉淀再出发:java中的HashMap.ConcurrentHashMap和Hashtable的认识 一.前言 很多知识在学习或者使用了之后总是会忘记的,但是如果把这些只是背后的原理理解了,并且记忆下 ...
- Java中HashTable和HashMap的区别
在Java中,HashTable和HashMap都是哈希表,那么它们有什么区别呢? 1.它们所继承的类不一样. HashTable和HashMap都实现了Map接口,但是它们所继承的类时不同的.H ...
- C#中Hashtable、Dictionary详解以及写入和读取对比
转载:http://www.cnblogs.com/chengxingliang/archive/2013/04/15/3020428.html 在本文中将从基础角度讲解HashTable.Dicti ...
- (转).Net中自定义类作为Dictionary的key详解
在定义数据结构时,Dictionary提供了快速查找数据的功能,另外Dictionary< TKey, TValue >属于key-value键值对数据结构,提供了泛型的灵活性,是数据结构 ...
- 1、C#中Hashtable、Dictionary详解以及写入和读取对比
在本文中将从基础角度讲解HashTable.Dictionary的构造和通过程序进行插入读取对比. 一:HashTable 1.HashTable是一种散列表,他内部维护很多对Key-Value键值对 ...
- HashMap中使用自定义类作为Key时,为何要重写HashCode和Equals方法
之前一直不是很理解为什么要重写HashCode和Equals方法,才只能作为键值存储在HashMap中.通过下文,可以一探究竟. 首先,如果我们直接用以下的Person类作为键,存入HashMap中, ...
- Hashtable HashMap
Hashtable和HashMap类有三个重要的不同之处.第一个不同主要是历史原因.Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现. ...
- java8中的HashMap
简介: HashMap: 具有很快的访问速度,但遍历顺序却是不确定的. HashMap最多只允许一条记录的键为null,允许多条记录的值为null. HashMap非线程安全,即任一时刻可以有多个线程 ...
随机推荐
- NetDMA
NetDMA provides operating system support for direct memory access (DMA) offload. TCP/IP uses NetDMA ...
- Win7 系统下 Firefox hostadmin插件无法修改Host
问题: win 7系统,今天用杀毒软件杀了一下毒,firefox hostAdmin插件无法修改Host了,提示“ write hosts file failed check permissions ...
- node.js开发中使用Node Supervisor实现监测文件修改并自动重启应用提高nodejs调试效率
在开发或调试Node.js应用程序的时候,当你修改js文件后,总是要按下CTRL+C终止程序,然后再重新启动,即使是修改一点小小的参数,也 总是要不断地重复这几个很烦人的操作.这是因为Node.js ...
- as3如何做出残影效果
在页游中,时不时能看到人物做一些快速移动动作如冲刺时,有残影效果,强化了画面表现.实际人肉眼之所以能看到残影的效果,是因为观察到的物体会在人视线中残留几十毫秒时间,当运动物体运动太快时,人肉眼所见未能 ...
- 点击页面其它地方隐藏div所想到的jQuery的delegate
在网页开发的过程中经常遇到的一个需求就是点击一div内部做某些操作,而点击页面其它地方隐藏该div.比如很多导航菜单,当菜单展开的时候,就会要求点击页面其它非菜单地方,隐藏该菜单. 先从最简单的开始, ...
- 利用iframe将div放置在object的上面
这两天在写一个用object上传照片的网页,在上传时,需要弹出一个进度条的div,我就按照正常的思维模式,将进度条div设为绝对定位,将其z-index设置的很大,结果,进度条div被object给遮 ...
- [转]CPU的位数与操作系统的位数的区别
转自:http://weiheyouchou.blog.hexun.com/35564976_d.html 随着近来AMD和Intel的64位CPU以及 Microsoft 64位操作系统的相继发布, ...
- HDU1051 贪心
Wooden Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- spring security使用数据库管理用户权限
<authentication-provider> <user-service> <user name="admin" password=" ...
- 20145334实验三《敏捷开发与XP实践》
实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 实验步骤 1.敏捷开发与XP 敏捷开发(Agile Dev ...