C#中的集合

  大多數集合都在System.Collections,System.Collections.Generic兩個命名空間。System.Collections.Generic是專門用於泛型集合。針對特定類型的集合類型位於System.Collections.Specialized;命名空間。線程安全的集合類位於System.Collections.Concurrent;命名空間。

      


一、下面列出非泛型和泛型集合的接口

非泛型集合接口          泛型集合接口              說明

ICollection            ICollection<T>           定義所有集合的大小(Count),枚舉器(foreach)和同步(copyto)方法,繼承自IEnumerable

IList               IList<T>               表示可按照索引單獨訪問的一組對象(像數組一樣)

IDictionary             IDictionary<T>           表示鍵/值對的集合

IComparer              IComparer<T>            定義類型爲比較兩個對象而實現的方法

IEqualityComparer         IEqualityComparer<T>        定義方法以支持對象的相等比較

IEnumerable            IEnumerable<T>           公開枚舉器。實現了該接口意味着允許foreach語句循環訪問集合中的元素

IEnumerator            IEnumerator<T>           支持在泛型集合上進行簡單迭代


基本上所有的接口都有泛型版本和非泛型版本。我這裏主要講的是泛型版本的集合,因爲泛型集合是類型安全,沒有裝箱拆箱操

作,性能上相對要好於非泛型版本。並且在項目中以泛型版本爲主。


Array,ArrayList,List<T>在我上一篇博客中有提及,這裏不再重複。有需要的朋友可以看我的上一篇博文

Queue


public class Queue<T> : IEnumerable<T>, ICollection, IEnumerable

對象的先進先出集合。內部實現也是素組。

Stack


public class Stack<T> : IEnumerable<T>, ICollection, IEnumerable
後進先出 (LIFO) 集合。內部實現也是素組。

Hashtable、Dictionary、SortedList<TKey,TValue>、SortedDictionary<TKey,TValue>的比較

HashTable


public class Hashtable : IDictionary, ICollection, 
	IEnumerable, ISerializable, IDeserializationCallback, ICloneable

HashTable是非泛型的,存儲的key value都是object類型。
1.HashTable是一種散列表,他內部維護很多對Key-Value鍵值對,其還有一個類似索引的值叫做散列值(HashCode),它是根據GetHashCode方法對Key通過一定算法獲取得到的,所有的查找操作定位操作都是基於散列值來實現找到對應的Key和Value值的。
2.我們需要使用一個算法讓散列值對應HashTable的空間地址儘量不重複,這就是散列函數(GetHashCode)需要做的事。
3.當一個HashTable被佔用一大半的時候我們通過計算散列值取得的地址值可能會重複指向同一地址,這就是哈希衝突。
在.Net中鍵值對在HashTable中的位置Position= (HashCode& 0x7FFFFFFF) % HashTable.Length,.net中是通過探測法解決哈希衝突的,當通過散列值取得的位置Postion以及被佔用的時候,就會增加一個位移x值判斷下一個位置Postion+x是否被佔用,如果仍然被佔用就繼續往下位移x判斷Position+2*x位置是否被佔用,如果沒有被佔用則將值放入其中。當HashTable中的可用空間越來越小時,則獲取得到可用空間的難度越來越大,消耗的時間就越多。
4.當前HashTable中的被佔用空間達到一個百分比的時候就將該空間自動擴容,在.net中這個百分比是72%,也叫.net中HashTable的填充因子爲0.72。例如有一個HashTable的空間大小是100,當它需要添加第73個值的時候將會擴容此HashTable.
5.這個自動擴容的大小是多少呢?答案是當前空間大小的兩倍最接近的素數,例如當前HashTable所佔空間爲素數71,如果擴容,則擴容大小爲素數131.


Dictionary<TKey,TValue>


public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
	ICollection<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, 
	IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, 
	IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, ISerializable, 
	IDeserializationCallback

Dictionary是泛型的類,類型安全的
1.Dictionary是一種變種的HashTable,它採用一種分離鏈接散列表的數據結構來解決哈希衝突的問題。
2.分離鏈接散列表是當散列到同一個地址的值存爲一個鏈表中。
3.這個變種HashTable的填充因子是1


HashTable和Dictionary的區別

1.HashTable不支持泛型,而Dictionary支持泛型。HashTable 的元素屬於 Object 類型,對值類型進行操作需要裝箱拆箱,比較耗時。

2.單線程程序中推薦使用 Dictionary, 有泛型優勢, 且讀取速度較快, 容量利用更充分。多線程程序中推薦使用 Hashtable, 默認的 Hashtable 允許單線程寫入, 多線程讀取, 對 Hashtable 進一步調用 Synchronized() 方法可以獲得完全線程安全的類型. 而 Dictionary 非線程安全, 必須人爲使用 lock 語句進行保護, 效率大減。


SortedList<TKey,TValue>


public class SortedList<TKey, TValue> : IDictionary<TKey, TValue>, 
	ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 
	IDictionary, ICollection, IEnumerable


SortedDictionary<TKey,TValue>


public class SortedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
	ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 
	IDictionary, ICollection, IEnumerable


SortedList<TKey,TValue>SortedDictionary<TKey,TValue>都實現了IDictionary<TKey, TValue>接口,都對key進行了排序。SortedList 泛型類是具有 O(log n) 檢索的二進制搜索樹,其中 n 是字典中元素的數目。就這一點而言,它與SortedDictionary<TKey,TValue>泛型類相似。這兩個類具有相似的對象模型,並且都具有 O(log n) 的檢索運算複雜度。

SortedList<TKey,TValue>SortedDictionary<TKey,TValue>的區別:

這兩個類的區別在於內存的使用以及插入和移除元素的速度:

      1.SortedList 使用的內存比 SortedDictionary 少。

      2.SortedDictionary 可對未排序的數據執行更快的插入和移除操作,它的運算複雜度爲 O(log n),而 SortedList 的運算複雜度爲 O(n)。

      3.如果使用排序數據一次性填充列表,則 SortedList 比 SortedDictionary 快。


HashSet<T>與SortedSet<T>

HashSet<T>


public class HashSet<T> : ISerializable, IDeserializationCallback, 
	ISet<T>, ICollection<T>, IEnumerable<T>, IEnumerable

SortedSet<T>


public class SortedSet<T> : ISet<T>, 
	ICollection<T>, IEnumerable<T>, ICollection, IEnumerable, ISerializable, 
	IDeserializationCallback

他們都實現了 System.Collections.Generic.ISet 接口.HashSet和SortSet主要的作用是用來進行兩個集合求交集、並集、差集等運算.集合中包含一組不重複出現且無特性順序的元素。前者不會自動排序,後者會加入元素後,自動排序。兩者都無法從特定位置訪問其中某個元素。a


線程安全的集合,都是以Concurrent命名開頭,所謂線程安全,當多個線程訪問同一個集合時,一次只能由一個線程訪問,不會引起一個線程在讀,一個線程在寫等同時進行的操作。

ConcurrentBag<T> 是線程安全的List<T>


public class ConcurrentBag<T> : IProducerConsumerCollection<T>, 
	IEnumerable<T>, ICollection, IEnumerable

ConcurrentDictionary<TKey,TValue> 是線程安全的Dictionary<TKey,TValue>


public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
	ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, 
	IDictionary, ICollection, IEnumerable

ConcurrentQueue<T> 是線程安全的Queue<T>

ConcurrentStack<T>是線程安全的Stack<T>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章