Java Set系列集合詳解:HashSet、LinkedHashSet、TreeSet底層原理與使用場景
一、Set系列集合概述
1. 核心特點
- 無序性:存取順序不一致(LinkedHashSet除外)。
- 唯一性:元素不重復。
- 無索引:無法通過索引直接訪問元素,不能使用普通
for
循環遍歷。
2. 常見實現類
實現類 | 特點 | 底層數據結構 |
---|---|---|
HashSet | 無序、唯一、無索引 | 哈希表(數組+鏈表/紅黑樹) |
LinkedHashSet | 有序(存取順序一致)、唯一 | 哈希表+雙向鏈表 |
TreeSet | 可排序(自然或自定義)、唯一 | 紅黑樹 |
二、Set接口常用方法
Set
繼承自Collection
接口,常用方法如下:
方法 | 說明 |
---|---|
boolean add(E e) | 添加元素,成功返回true |
void clear() | 清空集合 |
boolean remove(E e) | 刪除指定元素 |
`boolean contains(Object) | 判斷是否包含元素 |
int size() | 返回集合元素個數 |
三、各實現類詳解
1. HashSet
底層原理
- JDK8前:數組 + 鏈表。
- JDK8后:數組 + 鏈表 + 紅黑樹(鏈表長度≥8且數組長度≥64時觸發轉換)。
- 哈希值計算:通過重寫
hashCode()
和equals()
保證元素唯一性。
擴容機制
- 默認初始容量:16。
- 加載因子:0.75(當元素數量達到容量的75%時觸發擴容)。
代碼示例
Set<String> set = new HashSet<>();
set.add("A");
set.add("A"); // 添加失敗
System.out.println(set); // 輸出無序,如 [A, B]
2. LinkedHashSet
核心特點
- 繼承自
HashSet
,通過雙向鏈表維護插入順序。 - 性能略低于
HashSet
,但遍歷效率更高。
代碼示例
LinkedHashSet<String> linkedSet = new LinkedHashSet<>();
linkedSet.add("B");
linkedSet.add("A");
System.out.println(linkedSet); // 輸出順序固定為 [B, A]
3. TreeSet
排序規則
- 自然排序:元素需實現
Comparable
接口,重寫compareTo()
。 - 比較器排序:創建
TreeSet
時傳入Comparator
自定義規則。
代碼示例
// 自然排序(按年齡升序)
TreeSet<Student> treeSet = new TreeSet<>();
treeSet.add(new Student("Tom", 20));
treeSet.add(new Student("Alice", 18));
// 輸出按年齡排序:Alice(18) → Tom(20)
四、補充知識點
1. 線程安全性
HashSet
、TreeSet
、LinkedHashSet
均非線程安全。- 解決方案:使用
Collections.synchronizedSet()
包裝。
Set<String> syncSet = Collections.synchronizedSet(new HashSet<>());
2. 哈希沖突解決策略
- 鏈地址法(HashSet采用):沖突元素以鏈表形式存儲。
- 開放尋址法:線性探測或二次探測。
3. 紅黑樹簡介
- 一種自平衡二叉查找樹,保證插入、刪除、查找的時間復雜度為
O(log n)
。 - 特性:節點顏色交替、根節點為黑、葉子節點為黑、任意路徑黑節點數相同。
4. 性能對比
操作 | HashSet | LinkedHashSet | TreeSet |
---|---|---|---|
插入 | O(1) | O(1) | O(log n) |
刪除 | O(1) | O(1) | O(log n) |
查詢 | O(1) | O(1) | O(log n) |
有序性 | 無 | 插入順序 | 自然/自定義 |
五、應用場景總結
場景 | 推薦集合 |
---|---|
去重且無需順序 | HashSet |
去重且保留插入順序 | LinkedHashSet |
去重且需排序 | TreeSet |
高頻查詢 | HashSet |
需要線程安全 | Collections.synchronizedSet() |
六、常見面試題
-
HashSet如何保證元素唯一?
通過hashCode()
和equals()
方法:先比較哈希值,再通過equals
判斷內容是否相同。 -
TreeSet兩種排序方式如何選擇?
- 默認使用自然排序(需實現
Comparable
)。 - 若類無法修改或需多規則排序,使用
Comparator
。
- 默認使用自然排序(需實現
-
HashSet和HashMap的關系?
HashSet
底層基于HashMap
實現,元素存儲為HashMap
的鍵(值固定為PRESENT
占位對象)。
關注博主,獲取更多Java集合框架深度解析!