最近復習了一下集合,C# 關于集合的類蠻多,但我除了 List 那幾個經常用之外,其他的用得還真不多(只在小范圍使用),但其實,每個集合類都各有自己適用的場景,功能也很強大。尤其是,泛型類提供的那些方法,對于集合操作很方便,比如,很多方法都把委托作為參數,包括 Action、Fun、PRedicate 等,這樣,就可以使用匿名函數或 Lamda 表達式編程,代碼很簡潔,應該多試試,再用以前的 for 循環遍歷就有點 out 了~
一般的集合類都在 System.Collections 和 System.Collections.Generic 命名空間里,前者是非泛型集合,后則是泛型集合;線程安全的集合類位于 System.Collections.Concurrent 命名空間。
集合,都是一些《數據結構》中常見的結構,比如,列表、隊列、棧、雙向鏈表、字典、散列等等,其中,列表、雙向鏈表、字典、散列還有有序和無序之分等等。
其實,.Net 提供的每個集合類都繼承了相應的接口,不同接口的組合,就會出現不同的集合類。
| 集合 | 描述 |
| ArrayList,List<T> | 列表,List<T> 是 ArrayList 的泛型形式。 |
| Stack<T> | 棧 |
| Queue<T> | 隊列 |
| HashSet<T>,SortedSet<T> | 集,包含不重復元素的集合成為“集(set)”. 其中,HashSet<T> 集合包含不重復元素的無序列表;SortedSet<T> 集合包含不重復元素的有序列表。 |
| LinkedList<T> | 雙向鏈表 |
| Dictionary<TKey, TValue> | 字典,允許按照某個鍵來訪問元素。字典也稱為映射或散列表。字典的主要特征是能根據鍵快速查找值。也可以自由添加和刪除元素,這有點 List<T> 類,但沒有在內存中移動后續元素的性能開銷。 |
| SortedDictionary<TKey, TValue> | 有序字典,是一個二叉搜索樹,其中的元素根據鍵來排序。該鍵類型必須實現 IComparable<TKey> 接口。 |
| SortedList<TKey, TValue> | 有序鏈表,該類按照鍵給元素排序。 |
每個集合類類型,對不同的操作,性能也不同。實際項目中,可以綜合考慮下。
| 集合 | Add | Insert | Remove | Item | Sort | Find |
| List<T> | 如果集合必須重置大小,就是 O(1) 或 O(n) | O(n) | O(n) | O(1) | O(n log n),最壞情況 O(n^2) | O(n) |
| Stack<T> | Push(),如果棧必須重置大小,就是 O(1) 或 O(n) | N/A | Pop() O(1) | N/A | N/A | N/A |
| Queue<T> | Enqueue(),如果隊列必須重置大小,就是 O(1) 或 O(n) | N/A | Dequeue() O(1) | N/A | N/A | N/A |
| HashSet<T> | 如果集必須重置大小,就是 O(1) 或 O(n) | Add() O(1) 或 O(n) | O(1) | N/A | N/A | N/A |
| LinkedList<T> | AddLast() O(1) | AddAfter() O(1) | O(1) | N/A | N/A | O(n) |
| Dictionary<TKey, TValue> | O(1) 或 O(n) | N/A | O(1) | O(1) | N/A | N/A |
| SortedDictionary<TKey, TValue> | O(log n) | N/A | O(log n) | O(log n) | N/A | N/A |
| SortedList<TKey, TValue> | 無序數據為 O(n),如果必須重置大小,到列表的尾部就是 O(log n) | N/A | O(n) | 讀寫是 O(log n),如果鍵在列表中,就是 O(log n),否則,就是 O(n) | N/A | N/A |
* 注意:N/A 表示該操作不能應用于這種集合類型。
其中,
- O(1) 表示無論集合中有多少數據項,這個操作需要的時間都不變;
- O(n) 表示對于集合中的每個元素,需要增加的時間都是相同的;
- O(log n) 表示操作需要的時間隨集合中元素的增加而增加,但每個元素需要增加的時間,不是線性的,而不是呈對數曲線。
如何看這張表:
下載 Demo
新聞熱點
疑難解答