.NET 3.5 引入 HashSet<T>,.NET 4.0 緊隨推出 SortedSet<T>,兩者皆實作 ISet<T> 介面,對應數學「集合」定義:元素唯一、無特定順序。關鍵差異在於 SortedSet 內部採用紅黑樹維護有序性,插入/刪除/搜尋均為 O(log n),且自動保持元素排序。
| 特性 | HashSet<T> | SortedSet<T> |
|---|---|---|
| 底層結構 | 雜湊表 | 紅黑樹 (Red-Black Tree) |
| 元素順序 | 插入順序 | 自動排序 (預設遞增) |
| Contains 效能 | O(1) 平均 | O(log n) |
| Add 效能 | O(1) 平均 | O(log n) |
| 重複元素 | 自動忽略 | 自動忽略,回傳 false |
| 索引存取 | 不支援 | 不支援 |
| 額外功能 | 集合運算 (Union/Intersect/Except) | 繼承 HashSet 全部運算 + Min/Max/GetViewBetween |
.NET 3.5 時代需先 HashSet 去重再 List.Sort();.NET 4.0 直接使用 SortedSet:
var raw = new[] { 5, 9, 2, 1, 2, 2, 3, 7, 4, 9, 9 };
var sortedUnique = new SortedSet<int>(raw);
// 結果:1, 2, 3, 4, 5, 7, 9
字串與自訂型別同樣適用,只需實作 IComparable<T> 或提供 IComparer<T>。
回傳指定範圍內的子集合視圖,原集合異動即時反映:
var set = new SortedSet<int> { 1, 2, 3, 4, 5, 7, 9 };
var subset = set.GetViewBetween(2, 5); // 2, 3, 4, 5
subset.Add(6); // 擲出 ArgumentOutOfRangeException
O(1) 取得最小/最大值,無需遍歷:
Console.WriteLine($"Min: {set.Min()}, Max: {set.Max()}"); // Min: 1, Max: 9
需引用 System.Linq 命名空間。
var setA = new HashSet<char> { 'A', 'B', 'C' };
var setB = new HashSet<char> { 'C', 'D', 'E' };
setA.SymmetricExceptWith(setB); // A, B, D, E (對稱差集)
setA.UnionWith(setB); // A, B, C, D, E (聯集)
setA.ExceptWith(setB); // A, B (差集)
setA.IntersectWith(setB); // C (交集)
注意:HashSet 為就地修改,LINQ 對應運算則回傳新序列,記憶體模式不同。
HashSet<T>SortedSet<T>List<T> + Sort()Dictionary<TKey, TValue>SortedSet<T> 以紅黑樹為基礎,在保證元素唯一的前提下提供自動排序與豐富範圍操作,是 .NET 4.0+ 專案處理「去重+排序」複合需求的首選工具。善用 GetViewBetween、Min/Max 可大幅簡化區間統計與極值監控邏輯。