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

Java Collections 實現機制深度解析(下):包裝器與便利實現

     編輯:Java 相關知識

繼上篇介紹通用實現後,本文聚焦 包裝器實現 與 便利實現——兩種為特定場景提供增強功能或輕量替代的設計模式。

包裝器實現:裝飾者模式的經典應用

包裝器將現有集合委託操作,並疊加額外功能,符合 Decorator 模式。所有實現均為匿名類,透過 Collections 靜態工廠方法獲取。

同步包裝器:線程安全的透明層

六大核心介面均提供同步版本:

Collections.synchronizedCollection(Collection c)
Collections.synchronizedSet(Set s)
Collections.synchronizedList(List list)
Collections.synchronizedMap(Map m)
Collections.synchronizedSortedSet(SortedSet s)
Collections.synchronizedSortedMap(SortedMap m)

關鍵規則:所有存取必須透過返回的包裝器,切勿保留對底層集合的引用。建立慣用語:

List<String> list = Collections.synchronizedList(new ArrayList<>());

迭代時需手動同步(迭代屬多步操作,需原子性):

Collection<String> c = Collections.synchronizedCollection(myCollection);
synchronized (c) {
    Iterator<String> i = c.iterator(); // 必須在同步區塊內
    while (i.hasNext()) foo(i.next());
}

Map 視圖迭代陷阱:同步鎖必須鎖 Map 本身,而非視圖:

Map<String, String> m = Collections.synchronizedMap(new HashMap<>());
Set<String> s = m.keySet(); // 無需同步區塊
synchronized (m) { // 鎖 m,非 s!
    Iterator<String> i = s.iterator();
    while (i.hasNext()) foo(i.next());
}

缺點:無法呼叫包裝類特有的非介面方法(如 ArrayList.ensureCapacity)。

不可變包裝器:唯讀視角的守門人

透過攔截修改操作並拋出 UnsupportedOperationException 實現不可變性。兩大用途:

  1. 凍結集合:建立後不保留底層引用,絕對不可變。
  2. 唯讀傳遞:保留底層引用自用,對外暴露包裝器,實現「二等公民」唯讀存取。

六大介面對應靜態方法:unmodifiableCollection、unmodifiableSet、unmodifiableList、unmodifiableMap、unmodifiableSortedSet、unmodifiableSortedMap。

便利實現:小而美的專用工具

陣列的 List 視圖:Arrays.asList

返回陣列支援的 List 視圖,雙向同步修改。大小固定,add/remove 拋出異常。雙重用途:

  • 橋接陣列 API 與集合 API
  • 建立固定大小、高效能的列表:List<Object> list = Arrays.asList(new Object[size]);

不可變多重拷貝列表:Collections.nCopies

// 初始化 1000 個 null 的 ArrayList
List<String> list = new ArrayList<>(Collections.nCopies(1000, null));

// 尾部新增 69 個 "fruit bat"
lovablePets.addAll(Collections.nCopies(69, "fruit bat"));

不可變單例集合:Collections.singleton

單元素 Set,適用於:

// 移除集合中所有特定元素
c.removeAll(Collections.singleton(e));

// 移除 Map 中值為 LAWYER 的所有項目
profession.values().removeAll(Collections.singleton(LAWYER));

空集合常數

Collections.EMPTY_SET、Collections.EMPTY_LIST:避免建立新物件,作為需集合參數方法的空值傳遞。

善用包裝器與便利實現,能以最小代價獲得線程安全、不可變性與特定場景的高效能,是精通 Collections Framework 的關鍵進階技能。

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