Java中Set特性與常用方法示例詳解
更新時間:2026年02月11日 10:50:47 作者:敘白沖沖
Java中的Set是Collection接口的子接口,不允許存儲重復(fù)元素,且不保證順序(除特定實現(xiàn)外),下面給大家介紹Java中Set特性與常用方法,感興趣的朋友跟隨小編一起看看吧
Java 中的 Set 是 Collection 接口的子接口,不允許存儲重復(fù)元素,且不保證順序(除特定實現(xiàn)外)。以下是核心特性和常用方法:
一、核心特性
| 特性 | 說明 |
|---|---|
| 唯一性 | 不允許重復(fù)元素(基于 equals() 和 hashCode() 判斷) |
| 無序性 | 不保證插入順序(LinkedHashSet 和 TreeSet 除外) |
| 允許 null | 通常允許一個 null(TreeSet 不允許) |
| 無索引 | 沒有 get(index) 方法,不能通過索引訪問 |
二、主要實現(xiàn)類對比
| 實現(xiàn)類 | 底層結(jié)構(gòu) | 有序性 | 線程安全 | 適用場景 |
|---|---|---|---|---|
| HashSet | 哈希表(HashMap) | 無序 | 否 | 快速查找、去重 |
| LinkedHashSet | 哈希表 + 雙向鏈表 | 插入順序 | 否 | 需保持插入順序 |
| TreeSet | 紅黑樹(TreeMap) | 自然/定制排序 | 否 | 需排序范圍查詢 |
| CopyOnWriteArraySet | 數(shù)組 | 無序 | 是 | 讀多寫少并發(fā)場景 |
三、常用方法
1. 基礎(chǔ)操作(繼承自 Collection)
Set<String> set = new HashSet<>();
// 增
set.add("A"); // 添加成功返回 true,已存在返回 false
set.addAll(anotherSet); // 批量添加
// 刪
set.remove("A"); // 刪除指定元素
set.removeIf(s -> s.startsWith("A")); // 按條件刪除(Java 8+)
set.clear(); // 清空所有元素
// 查
set.contains("A"); // 判斷是否包含,O(1) 時間
set.isEmpty(); // 是否為空
set.size(); // 元素個數(shù)
// 遍歷
for (String s : set) { }
set.forEach(System.out::println);
Iterator<String> it = set.iterator();2. 批量操作(集合運算)
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3)); Set<Integer> set2 = new HashSet<>(Arrays.asList(2, 3, 4)); // 交集 set1.retainAll(set2); // set1 變?yōu)?[2, 3] // 并集 set1.addAll(set2); // set1 變?yōu)?[1, 2, 3, 4] // 差集 set1.removeAll(set2); // set1 中去掉 set2 的元素 // 包含判斷 set1.containsAll(set2); // set1 是否包含 set2 所有元素
四、各實現(xiàn)類特性詳解
1. HashSet(最常用)
Set<String> set = new HashSet<>(); // 初始容量16,負載因子0.75 // 自定義初始容量(減少擴容次數(shù)) Set<String> set = new HashSet<>(1000); // 去重原理:先比較 hashCode,再比較 equals
?? 注意:元素必須正確重寫 hashCode() 和 equals()
// 錯誤示例:自定義類未重寫導(dǎo)致去重失敗
class Person {
String name;
// 未重寫 hashCode/equals,默認按地址比較
}
// 正確做法
class Person {
String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}2. LinkedHashSet(保持插入順序)
Set<String> set = new LinkedHashSet<>();
set.add("B");
set.add("A");
set.add("C");
// 遍歷順序:B, A, C(與插入順序一致)3. TreeSet(自動排序)
// 自然排序(元素實現(xiàn) Comparable) Set<Integer> set = new TreeSet<>(); set.add(3); set.add(1); set.add(2); // 遍歷結(jié)果:1, 2, 3 // 定制排序(Comparator) Set<String> set = new TreeSet<>(Comparator.reverseOrder()); Set<Person> set = new TreeSet<>(Comparator.comparing(Person::getAge)); // 特有方法(SortedSet 接口) TreeSet<Integer> ts = new TreeSet<>(); ts.first(); // 最小元素 ts.last(); // 最大元素 ts.headSet(5); // 小于5的子集 ts.tailSet(5); // 大于等于5的子集 ts.subSet(2, 5); // [2, 5) 范圍的子集
五、Stream API 操作(Java 8+)
List<Integer> list = Arrays.asList(1, 2, 2, 3, 3, 3);
// List 轉(zhuǎn) Set 去重
Set<Integer> set = list.stream().collect(Collectors.toSet());
// 過濾 + 收集
Set<String> result = set.stream()
.filter(s -> s.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toCollection(LinkedHashSet::new));
// 找最大/最小
Optional<Integer> max = set.stream().max(Integer::compareTo);六、線程安全方案
// 1. Collections 包裝(讀寫都加鎖,性能差) Set<String> syncSet = Collections.synchronizedSet(new HashSet<>()); // 2. CopyOnWriteArraySet(讀多寫少推薦) Set<String> cowSet = new CopyOnWriteArraySet<>(); // 寫操作復(fù)制整個數(shù)組,讀操作無鎖 // 3. ConcurrentHashMap 的 KeySet(Java 8+) Set<String> concurrentSet = ConcurrentHashMap.newKeySet();
七、常見面試題
| 問題 | 答案 |
|---|---|
HashSet 如何檢查重復(fù)? | 先比較 hashCode,相同再比較 equals |
為什么重寫 equals 必須重寫 hashCode? | 保證相等對象有相同哈希值,否則 HashSet 會去重失敗 |
TreeSet 插入 null 報錯? | 因為需要比較排序,null 無法比較 |
HashSet 和 HashMap 關(guān)系? | HashSet 底層是 HashMap,元素作為 Key,Value 是固定對象 |
到此這篇關(guān)于Java中Set特性與常用方法的文章就介紹到這了,更多相關(guān)java set方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java.net.MalformedURLException異常的解決方法
下面小編就為大家?guī)硪黄猨ava.net.MalformedURLException異常的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05
Reactor 多任務(wù)并發(fā)執(zhí)行且結(jié)果按順序返回第一個
這篇文章主要介紹了Reactor 多任務(wù)并發(fā)執(zhí)行且結(jié)果按順序返回第一個,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下2022-09-09
java設(shè)計模式-單例模式實現(xiàn)方法詳解
單例模式,屬于創(chuàng)建類型的一種常用的軟件設(shè)計模式。通過單例模式的方法創(chuàng)建的類在當(dāng)前進程中只有一個實例(根據(jù)需要,也有可能一個線程中屬于單例2021-07-07

