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

Java Collections 工具類深度解析:核心方法、數據結構與實戰技巧

     編輯:Java 相關知識

Collections vs Collection 區別

  • Collection:頂層集合接口 (List、Set、Queue 父接口)
  • Collections:java.util.Collections 工具類,全 static 方法,操作/返回集合

核心靜態方法分類速查

類別方法說明
排序sort(List)自然序排序 (元素需 Comparable)
sort(List, Comparator)指定比較器排序
reverse(List)反轉順序
shuffle(List)隨機打亂 (洗牌算法)
查找/替換binarySearch(List, key)二分查找 (列表必須有序)
binarySearch(List, key, Comparator)指定比較器二分查找
max(Collection) / min(Collection)最大/最小元素 (自然序)
max(Collection, Comparator)指定比較器最大/最小
replaceAll(List, oldVal, newVal)替換所有匹配元素
同步包裝synchronizedCollection(Collection)線程安全包裝 (裝飾器模式)
synchronizedList/List/Set/Map各類型專用包裝
unmodifiableCollection/List/Set/Map不可變視圖 (只讀)
checkedCollection/List/Set/Map類型安全檢查視圖 (運行時檢查)
特殊集合emptyList/Set/Map()不可變空集合 (單例)
singleton(obj) / singletonList/Map單元素不可變集合
nCopies(n, obj)N 個引用同一對象的列表
frequency(Collection, obj)統計元素出現次數
工廠/轉換enumeration(Collection)轉 Enumeration (舊 API 兼容)
list(Enumeration)Enumeration 轉 ArrayList
addAll(Collection, elements...)批量添加 (可變參數)

數據結構實現原理 (Collections 內部類)

1. 同步包裝器 (SynchronizedWrapper)

// 核心思想:裝飾器模式,所有方法 synchronized 加鎖
static class SynchronizedList extends SynchronizedCollection implements List {
    final List list;
    final Object mutex; // 鎖對象,默認 this,可傳入外部鎖
    
    public E get(int index) {
        synchronized (mutex) { return list.get(index); }
    }
    // ... 所有方法同步
    
    // 迭代器需手動同步!
    public Iterator iterator() {
        return list.iterator(); // 返回原始迭代器,用戶必須手動 synchronized(mutex)
    }
}

關鍵警示:synchronizedList 迭代時必須手動同步鎖對象,否則非線程安全:

List syncList = Collections.synchronizedList(new ArrayList<>());
// 錯誤:併發修改異常
for (String s : syncList) { ... }

// 正確:手動同步
synchronized (syncList) {
    for (String s : syncList) { ... }
}

// 或用 CopyOnWriteArrayList (無需同步遍歷)

2. 不可變視圖 (UnmodifiableWrapper)

static class UnmodifiableList extends UnmodifiableCollection implements List {
    final List list;
    public E get(int index) { return list.get(index); }
    public E set(int index, E element) { throw new UnsupportedOperationException(); }
    public void add(int index, E element) { throw new UnsupportedOperationException(); }
    // ... 所有修改方法拋異常
}

注意:僅是視圖,底層集合修改仍會反映到視圖。真正不可變請用 List.of() (JDK 9+) 或 ImmutableList (Guava)。

3. 類型安全檢查 (CheckedWrapper)

List safe = Collections.checkedList(new ArrayList<>(), String.class);
safe.add("OK");
safe.add(123); // 運行時拋 ClassCastException (而非編譯錯誤),用於調試泛型擦除問題

實戰技巧與最佳實踐

1. 自定義比較器排序

List users = ...;
// 多字段排序:先按年齡升序,再按姓名降序
users.sort(Comparator.comparing(User::getAge)
    .thenComparing(User::getName, Comparator.reverseOrder()));

// 或 Collections.sort
Collections.sort(users, (u1, u2) -> {
    int c = Integer.compare(u1.getAge(), u2.getAge());
    if (c != 0) return c;
    return u2.getName().compareTo(u1.getName()); // 姓名降序
});

2. 二分查找前提:必須有序

List sorted = Arrays.asList(1, 3, 5, 7, 9);
int idx = Collections.binarySearch(sorted, 5); // 返回 2
int notFound = Collections.binarySearch(sorted, 4); // 返回 -3 (-(插入點+1))
// 插入點 = -(-3) - 1 = 2,即應插入索引 2 保持有序

3. 洗牌算法

List deck = new ArrayList<>(52);
// 初始化...
Collections.shuffle(deck); // Fisher-Yates 洗牌,O(n),均勻隨機
// 指定 Random 種子可復現
Collections.shuffle(deck, new Random(42));

4. 空集合單例模式

// 避免創建多個空列表對象
public List getEmpty() {
    return Collections.emptyList(); // 返回同一單例 EMPTY_LIST
}

// 方法參數防空
public void process(List items) {
    List list = items != null ? items : Collections.emptyList();
    // 安全遍歷
}

5. 單例集合

Set singleton = Collections.singleton("ONLY_ONE"); // 不可變、高效
Map singletonMap = Collections.singletonMap("key", "value");

現代替代方案 (JDK 9+ / 第三方庫)

Collections 方法現代替代優勢
unmodifiableListList.of() / List.copyOf()真正不可變、內存緊湊、編譯期類型安全
singletonListList.of(element)同上
emptyListList.of()同上
synchronizedListCopyOnWriteArrayList / 並發集合無鎖遍歷、更高並發性能
checkedList編譯期泛型 + 單元測試靜態檢查優於運行時
sortlist.sort(comparator)實例方法、鏈式調用
binarySearchCollections.binarySearch 仍通用無直接替代
shuffleCollections.shuffle 仍通用無直接替代
frequencyCollections.frequency / Stream filter().count()Stream 更靈活

性能與線程安全總結

包裝類型讀性能寫性能遍歷安全適用場景
Collections.synchronizedXxx鎖開銷鎖開銷需手動同步低併發、舊代碼兼容
CopyOnWriteArrayList極快 (無鎖)慢 (複製數組)✅ 安全讀多寫極少、遍歷頻繁
ConcurrentHashMap極快 (分段/CAS)快 (細粒度鎖)✅ 弱一致性高併發 Map
List.of / Set.of極快 (不可變)不支持✅ 天然安全只讀數據、常量、配置

避坑指南

  1. 同步包裝迭代器非線程安全:必須手動 synchronized(list) 遍歷
  2. 不可變視圖非深度不可變:底層集合變更會反映,元素對象可變性不受控
  3. binarySearch 前提必須有序:無序列表結果未定義
  4. shuffle 修改原列表:非線程安全,併發環境需外部同步
  5. nCopies 共享引用:Collections.nCopies(3, new ArrayList()) 三個引用指向同一列表
  6. 生產環境優先並發集合:CopyOnWriteArrayList、ConcurrentHashMap 替代同步包裝

總結

Collections 是 Java 集合框架的「瑞士軍刀」,提供排序、查找、同步包裝、不可變視圖、特殊單例、工廠轉換等靜態工具方法。核心實現基於裝飾器模式,同步包裝器需注意迭代器手動同步,不可變視圖僅屏蔽修改方法。現代開發優先使用 JDK 9+ List.of()、並發集合、實例方法 list.sort(),Collections 仍作為補充工具 (shuffle、binarySearch、frequency 等) 發揮價值。掌握其 API 分類、實現原理、線程安全邊界與現代替代,能寫出更簡潔、高效、安全的集合操作代碼。

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