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

計算機程序思維邏輯 (54):Collections 適配器與裝飾器模式深度解析

     編輯:Java 綜合教學

計算機程序思維邏輯 (54):Collections 適配器與裝飾器模式深度解析

Java Collections 工具類的第二類方法:返回容器介面對象,完美演示了適配器與裝飾器兩大經典設計模式。本文結合 JDK 源碼,剖析空容器、單例容器、檢查型、同步型、不可修改型包裝器的實現細節與適用邊界。

一、適配器模式:將「非容器」轉為「標準容器」

1.1 空容器適配器

List<String> list = Collections.emptyList();  // 返回靜態單例 EmptyList
Map<K,V> map = Collections.emptyMap();
Set<E> set = Collections.emptySet();
  • 核心價值:避免返回 null,調用者無需判空,統一流程;靜態單例節省內存/創建開銷
  • 限制:不可修改,調用 add/remove 拋 UnsupportedOperationException
  • 源碼:EmptyList 繼承 AbstractList,size()=0,所有寫操作拋異常

1.2 單例容器適配器

Set<String> set = Collections.singleton("hello");
List<String> list = Collections.singletonList("world");
Map<K,V> map = Collections.singletonMap("k", "v");
  • 內部類 SingletonSet 只存儲單一元素引用,size()=1,iterator() 返回單元素迭代器
  • 同樣不可修改,適用於臨時構建參數、返回值
  • 實戰技巧:list.removeAll(Collections.singleton("b")) 刪除所有指定元素

1.3 其他適配器

  • newSetFromMap(Map<E,Boolean>):Map → Set 視圖
  • asLifoQueue(Deque):Deque → 後進先出 Queue
  • nCopies(n, o):返回包含 n 個相同引用的不可修改 List

二、裝飾器模式:在保持介面不變下增強行為

2.1 不可修改裝飾器 unmodifiableXxx()

  • 包裝原容器,讀操作委派,寫操作拋異常
  • 典型場景:將內部集合暴露給外部/三方代碼,防止誤修改
  • 源碼:UnmodifiableCollection 實現 Collection,構造器檢查 null,迭代器 remove() 拋異常

2.2 類型安全裝飾器 checkedXxx()

  • 解決泛型擦除導致的「運行期類型污染」:List<Integer> list = new ArrayList<>(); list.add("str"); // 編譯通過,運行不報錯
  • Collections.checkedList(list, Integer.class) 包裝後,add("str") 拋 ClassCastException
  • 源碼:CheckedCollection 在 add 時調用 typeCheck() 驗證 type.isInstance(o)

2.3 線程安全裝飾器 synchronizedXxx()

  • 對所有方法加 synchronized(this) 鎖,粗粒度同步
  • 性能一般,高併發優先用 java.util.concurrent 並發容器 (ConcurrentHashMap, CopyOnWriteArrayList 等)

三、設計模式對比總結

維度適配器裝飾器
目的介面轉換:將 A 介面適配為 B 介面行為增強:保持介面,動態添加職責
Collections 例emptyList、singleton、newSetFromMapunmodifiable、checked、synchronized
核心類結構實現目標介面,內部持有被適配對象實現目標介面,內部持有被裝飾對象
是否可疊加通常單層支持多層疊加 (如 synchronized + unmodifiable)

四、實戰選型指南

  1. 返回空集合 → Collections.emptyList() (唯讀) / new ArrayList<>() (可寫)
  2. 構建單元素參數 → Collections.singleton(x)
  3. 防禦性編程:對外暴露集合前 → unmodifiableXxx()
  4. 混合舊代碼/無泛型代碼交互 → checkedXxx(list, Type.class)
  5. 簡單多線程訪問 → synchronizedXxx();高併發 → 並發包容器
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved