首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

C# 集合深度對比:HashSet、HashTable、TreeSet 核心原理與選型指南

     編輯:Java 綜合教學

C# 集合深度對比:HashSet、HashTable、TreeSet 核心原理與選型指南

本文聚焦 C#/.NET 體系下的三大經典集合:**HashSet<T>**、**Hashtable**、**TreeSet**(實為 SortedSet<T>),從底層數據結構、核心 API、性能特徵、適用場景四個維度深度對比,助你精準選型。

一、HashSet<T>:高性能集合運算利器

1. 核心定位

  • 基於**哈希表**實現,專為**集合運算**(並集、交集、差集、子集判斷)優化
  • 元素**唯一、無序**,單元素操作 O(1) 平均複雜度
  • .NET Framework 3.5+ 引入,泛型、類型安全

2. 關鍵構造函數

new HashSet<T>()                                    // 默認比較器
new HashSet<T>(IEnumerable<T> collection)           // 從集合初始化
new HashSet<T>(IEqualityComparer<T> comparer)       // 自定義相等比較
new HashSet<T>(IEnumerable<T>, IEqualityComparer<T>)

3. 核心集合運算方法 (修改當前實例)

4. 其他常用方法

  • Add/Remove/Contains/Clear/Count
  • RemoveWhere(predicate)、TrimExcess() (釋放多餘容量)

二、TreeSet / SortedSet<T>:有序集合的紅黑樹實現

.NET 中**無 TreeSet 類**,有序集合為 SortedSet<T> (Framework 4.0+),底層同為**紅黑樹**,功能對標 Java TreeSet。

1. 核心特徵

  • 元素**唯一、有序**(升序),插入/刪除/查找 O(log n)
  • 要求元素實現 IComparable<T> 或構造時傳入 IComparer<T>
  • **不允許 null 值** (紅黑樹比較需非空)
  • 提供 Min/Max、GetViewBetween(lower, upper) 範圍視圖、Reverse() 逆序枚舉

2. HashSet vs SortedSet 核心差異

方法數學意義說明
UnionWith(other)並集 ∪當前集合添加 other 中所有元素
IntersectWith(other)交集 ∩僅保留當前與 other 共有元素
ExceptWith(other)差集 −移除 other 中存在的元素
SymmetricExceptWith(other)對稱差集 △保留僅在其中一個集合出現的元素
IsSubsetOf(other)子集 ⊆當前元素全在 other 中
IsProperSubsetOf(other)真子集 ⊂子集且不相等
IsSupersetOf(other)超集 ⊇other 元素全在當前中
Overlaps(other)相交至少有一個共同元素
SetEquals(other)相等 =元素完全相同
維度HashSet<T>SortedSet<T>
底層結構哈希表 (桶+鏈表/樹)紅黑樹 (自平衡 BST)
順序無序升序 (可定制 Comparer)
Null 支持允許 1 個 null不允許
單操作複雜度O(1) 平均O(log n)
集合運算豐富 (原地修改)較少 (需手動實現)
範圍查詢不支持GetViewBetween 高效支持
內存佔用較大 (負載因子預留)較小 (緊湊節點)

三、Hashtable:非泛型時代的同步哈希表

Hashtable 為非泛型集合** (存 Object),**強烈建議新代碼改用 Dictionary<TKey, TValue>** 或 ConcurrentDictionary<TKey, TValue>。本節僅供維護舊代碼參考。

1. 核心特徵

  • **線程安全**:所有公共方法均 synchronized (鎖整個表)
  • Key/Value **均不允許 null**
  • 默認初始容量 11,擴容策略 newCapacity = old * 2 + 1 (質數傾向)
  • 使用 Key 的 GetHashCode() 定位桶位,Equals() 解決衝突

2. Hashtable vs Dictionary<TKey, TValue> vs ConcurrentDictionary

特性HashtableDictionary<TKey,TValue>ConcurrentDictionary<TKey,TValue>
泛型否 (Object)是是
線程安全是 (全表鎖)否是 (細粒度鎖/CAS)
Null Key/Value全禁允許Value 允許, Key 禁
性能 (單線程)低 (鎖開銷)最高略低於 Dictionary
性能 (多線程讀多)極低需外部鎖高 (無鎖讀)
推薦場景舊代碼維護單線程/外部同步高併發 KV 存儲

四、選型決策樹

需要 Key-Value 映射?
    ├─ 是 → 高併發? → 是 → ConcurrentDictionary
    │                └─ 否 → Dictionary
    └─ 否 → 需要有序/範圍查詢?
                 ├─ 是 → SortedSet / SortedDictionary
                 └─ 否 → 需要集合運算(並/交/差)?
                          ├─ 是 → HashSet
                          └─ 是 → 只需去重/存在性判斷 → HashSet
                                   └─ 兼容舊代碼 → Hashtable (不推薦新用)

五、總結

  • HashSet<T>:去重、存在性判斷、集合運算首選,O(1) 平均性能。
  • SortedSet<T>:有序去重、範圍查詢、Min/Max 獲取首選,O(log n) 穩定性能。
  • Hashtable:歷史產物,新代碼**禁用**,遷移至 Dictionary (單線程) 或 ConcurrentDictionary (多線程)。
  • 自定義比較邏輯時,牢記:HashSet 用 IEqualityComparer,SortedSet 用 IComparer,Dictionary 同 HashSet。

掌握三者底層結構差異(哈希表 vs 紅黑樹)、線程安全模型、API 設計哲學,即可在 .NET 集合選型中游刃有餘。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved