.net不同集合类型及使用场合

HashTable、HashSet和Dictionary的区别 - @大龙哥 - 博客园 (cnblogs.com)

哈希表Hashtable与字典表Dictionary<K,V>的比较。_快乐人生-CSDN博客_哈希表和字典区别

浅谈ConcurrentDictionary与Dictionary - 萌萌丶小魔王 - 博客园 (cnblogs.com)

记一次 .NET 某机械臂智能机器人控制系统MRS CPU爆高分析 - 一线码农 - 博客园 (多线程操作Dictioanry问题)

 

1):单线程程序中推荐使用 Dictionary, 有泛型优势, 且读取速度较快, 容量利用更充分.
2):多线程程序中推荐使用 Hashtable, 默认的 Hashtable 允许单线程写入, 多线程读取, 对 Hashtable 进一步调用 Synchronized()方法可以获得完全线程安全的类型. 而Dictionary 非线程安全, 必须人为使用 lock 语句进行保护, 效率大减.
3):Dictionary 有按插入顺序排列数据的特性 (注: 但当调用 Remove() 删除过节点后顺序被打乱), 因此在需要体现顺序的情境中使用 Dictionary 能获得一定方便.

 

HashTable中的key/value均为object类型,由包含集合元素的存储桶组成。存储桶是 HashTable中各元素的虚拟子组,与大多数集合中进行的搜索和检索相比,存储桶可令搜索和检索更为便捷。每一存储桶都与一个哈希代码关联,该哈希代码是使用哈希函数生成的并基于该元素的键。HashTable的优点就在于其索引的方式,速度非常快。如果以任意类型键值访问其中元素会快于其他集合,特别是当数据量特别大的时候,效率差别尤其大。

HashTable的应用场合有:做对象缓存,树递归算法的替代,和各种需提升效率的场合。

 

         1.Dictionary-相当于字典可以通过过索引(hash值)速添加、删除、查找】:如果需要非常快地添加、删除和查找项目,而且不关心集合中项目的顺序,那么首先应该考虑使用 System.Collections.Generic.Dictionary<TKey, TValue>(或者您正在使用 .NET Framework 1.x,可以考虑 Hashtable)。三个基本操作(添加、删除和包含)都可快速操作,即使集合包含上百万的项目。

         2.List<T>-相当于列表、表格可以保证集合的顺序,查找、删除、添加相对较慢】:如果您的使用模式很少需要删除和大量添加,而重要的是保持集合的顺序,那么您仍然可以选择 List<T>。虽然查找速度可能比较慢(因为在搜索目标项目时需要遍历基础数组),但可以保证集合会保持特定的顺序。

         3.Queue<T>-相当于排队入场Stack<T> 相当于子弹夹:您可以选择 Queue<T> 实现先进先出 (FIFO) 顺序或 Stack<T> 实现后进先出 (LIFO) 顺序。虽然 Queue<T> 和 Stack<T> 都支持枚举集合中的所有项目,但前者只支持在末尾插入和从开头删除,而后者只支持从开头插入和删除。

         4.LinkedList<T> :如果需要在实现快速插入的同时保持顺序,那么使用新的 LinkedList<T> 集合可帮助您提高性能。与 List<T> 不同,LinkedList<T> 是作为动态分配的对象链实现。与 List<T> 相比,在集合中间插入对象只需要更新两个连接和添加新项目。从性能的角度来看,链接列表的缺点是垃圾收集器会增加其活动因为它必须遍历整个列表以确保没有对象没有被释放。另外,由于每个节点相关的开销以及每个节点在内存中的位置等原因,大的链接列表可能会出现性能问题。虽然将项目插入到 LinkedList<T> 的实际操作比在 List<T> 中插入要快得多,但是找到要插入新值的特定位置仍需遍历列表并找到正确的位置。

 

 

以下为转别人的

在C#中,数组由于是固定长度的,所以常常不能满足我们开发的需求。

由于这种限制不方便,所以出现了ArrayList。

ArrayList、List<T>


ArrayList是可变长数组,你可以将任意多的数据Add到ArrayList里面。其内部维护的数组,当长度不足时,会自动扩容为原来的两倍。

但是ArrayList也有一个缺点,就是存入ArrayList里面的数据都是Object类型的,所以如果将值类型存入和取出的时候会发生装箱、拆箱操作(就是值类型与引用类型之间的转换),这个会影响程序性能。在.Net 2.0泛型出现以后,就提供了List<T>。

List<T>是ArrayList的泛型版本,它不再需要装箱拆箱,直接取,直接用,它基本与ArrayList一致,不过在使用的时候要先设置好它的类型,而设置好类型之后,不是这种类型的数据,是不允许Add进去的。

就性能来说,如果要存进数组的只有一种数据,那么无疑List<T>是最优选择。

List<int> ListInt = new List<int>();

如果一个变长数组,又要存int,又要存string。那么就只能用ArrayList。

HashTable(哈希表)、Dictionary<T,T>


HashTable是一种根据key查找非常快的键值数据结构,不能有重复key,而且由于其特点,其长度总是一个素数,所以扩容后容量会比2倍大一点点,加载因子为0.72f。

当要大量使用key来查找value的时候,HashTable无疑是最有选择,HashTable与ArrayList一样,是非泛型的,value存进去是object,存取会发生装箱、拆箱,所以出现了Dictionary<T,T>。

Dictionary<T,T>是HashTable的泛型版本,存取同样快,但是不需要装箱和拆箱了。而且,其优化了算法,Hashtable是0.72,它的浪费容量少了很多。

Dictionary<string,Person> Dic = new Dictionary<string,Person>();

HashSet<T>


HashSet<T>类,算法,存储结构都与哈希表相同,主要是设计用来做高性能集运算的,例如对两个集合求交集、并集、差集等。集合中包含一组不重复出现且无特定顺序的元素。

Queue、Queue<T>


Queue队列,Queue<T>泛型队列,大学都学过,队列,先进先出,很有用。

Stack、Stack<T>


Stack堆栈,先进后出。

SortedList、SortedList<TKey,TValue>


SortedList集合中的数据是有序的。可以通过key来匹配数据,也可以通过int下标来获取数据。

添加操作比ArrayList,Hashtable略慢;查找、删除操作比ArrayList快,比Hashtable慢。

SortedDictionary<TKey,TValue>


SortedDictionary<TKey,TValue>相比于SortedList<TKey,TValue>其性能优化了,SortedList<TKey,TValue>其内部维护的是数组而SortedDictionary<TKey,TValue>内部维护的是红黑树(平衡二叉树)的一种,因此其占用的内存,性能都好于SortedDictionary<TKey,TValue>。唯一差在不能用下标取值。

ListDictionary(单向链表),LinkedList<T>(双向链表)


List<T>,ArrayList,Hashtable等容器类,其内部维护的是数组Array来,ListDictionary和LinkedList<T>不用Array,而是用链表的形式来保存。链表最大的好处就是节约内存空间。

ListDictionary是单向链表。

LinkedList<T>双向链表。双向链表的优势,可以插入到任意位置。

HybridDictionary


HybridDictionary的类,充分利用了Hashtable查询效率高和ListDictionary占用内存空间少的优点,内置了Hashtable和ListDictionary两个容器,添加数据时内部逻辑如下:

当数据量小于8时,Hashtable为null,用ListDictionary保存数据。

当数据量大于8时,实例化Hashtable,数据转移到Hashtable中,然后将ListDictionary置为null。

BitArray


BitArray这个东东是用于二进制运算,"或"、"非"、"与"、"异或非"等这种操作,只能存true或false;

应用场景


ArrayList,List<T>:变长数组;

HashTable,Dictionary<T,T>:频繁根据key查找value;

HashSet<T>:集合运算;

Queue、Queue<T>:先进先出;

Stack、Stack<T>:堆栈,先进先出;

SortedList、SortedList<TKey,TValue>:哈希表,要通过下标,又要通过key取值时,可选用;

ListDictionary:单向链表,每次添加数据时都要遍历链表,数据量大时效率较低,数据量较大且插入频繁的情况下,不宜选用。

LinkedList<T>:双向链表;

HybridDictionary:未知数据量大小时,可用。

SortedDictionary<TKey,TValue>:SortedList<TKey,TValue>的优化版,内部数组转平衡二叉树。

BitArray:二进制运算时可选用;

posted @ 2019-01-25 16:08  无聊的蚂蚁  阅读(481)  评论(0编辑  收藏  举报