繼上篇介紹通用實現後,本文聚焦 包裝器實現 與 便利實現——兩種為特定場景提供增強功能或輕量替代的設計模式。
包裝器將現有集合委託操作,並疊加額外功能,符合 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 實現不可變性。兩大用途:
六大介面對應靜態方法:unmodifiableCollection、unmodifiableSet、unmodifiableList、unmodifiableMap、unmodifiableSortedSet、unmodifiableSortedMap。
Arrays.asList返回陣列支援的 List 視圖,雙向同步修改。大小固定,add/remove 拋出異常。雙重用途:
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 的關鍵進階技能。