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

《Thinking in Java》讀書筆記第 11 章:持有你的對象 — 容器框架深度解析

     編輯:Java 相關知識

第 11 章《Holding Your Objects》系統闡述 Java 容器框架的核心設計哲學、泛型機制、主要容器類別(Collection/Map)的選型指南、迭代器模式應用與 foreach 語法糖原理。本文結合原書精華與實戰經驗,為你構建完整的容器知識體系。


核心觀點速覽

  • 程序運行時動態創建對象,無法預知數量 → **不能依賴命名引用**
  • 數組固定大小、僅支援基本類型 → **容器類自動擴容、持有對象引用**
  • 泛型:編譯期類型檢查 + 消除強制轉型 + 更清晰語法
  • 面向接口編程:List<T> list = new ArrayList<>(); 僅在創建點指定具體實現

一、泛型與類型安全容器

泛型三大價值

  1. 編譯期檢查:防止錯誤類型放入容器
  2. 自動類型轉換:取出元素無需強轉
  3. 向上轉型保持:List<Dog> 可賦值給 List<? extends Animal>

創建點原則

// 僅在 new 時指定具體類型,其餘處使用接口
List list = new ArrayList<>();
Map map = new HashMap<>();
Set set = new HashSet<>();

二、添加元素組的最佳實踐

Collections.addAll() — 首選方案

List list = new ArrayList<>();
Collections.addAll(list, "a", "b", "c"); // 效能最優、語法最簡

Arrays.asList() 陷阱與解法

  • 返回固定大小 List,**不可添加/刪除**元素
  • 類型推斷可能不準確 → 使用顯式類型參數:List list = Arrays.asList("a", "b");

三、容器類別體系全景圖

Collection vs Map — 根本區別

維度CollectionMap
槽位結構單個元素鍵值對
核心接口List / Set / QueueMap / SortedMap
重複性List 可重複,Set 唯一Key 唯一,Value 可重複

List 實現選型指南

實現底層結構隨機訪問中間增刪適用場景
ArrayList動態數組O(1) 快O(n) 慢頻繁讀、少量增刪、末尾追加
LinkedList雙向鏈表O(n) 慢O(1) 快頻繁中間增刪、棧/隊列/雙端隊列

關鍵提示:subList() 返回視圖,修改視圖影響原列表;使用索引操作避開 equals() 行為差異。

Set 實現選型指南

實現底層結構有序性查找效能適用場景
HashSet哈希表無序O(1) 最快去重、成員測試、高頻查找
TreeSet紅黑樹自然序/定製序O(log n)需要排序、範圍查詢
LinkedHashSet哈希表+鏈表插入序O(1)保持插入順序 + 快速查找

Map 實現選型指南

  • HashMap:高效雜湊,無序,JDK 8+ 鏈表轉紅黑樹優化碰撞
  • TreeMap:紅黑樹,Key 有序,範圍查詢
  • LinkedHashMap:保持插入/訪問順序,LRU 快取實現首選
  • WeakHashMap:Key 弱引用,緩存場景自動清理
  • ConcurrentHashMap:分段鎖/CAS,高併發首選

四、迭代器模式 — 統一遍歷抽象

Iterator 核心契約

  • hasNext() / next() / remove()
  • 分離遍歷邏輯與數據結構:客戶端代碼不依賴具體容器類型
  • remove() 必須在 next() 之後調用,否則拋 IllegalStateException

ListIterator — 雙向游標增強

  • 僅 List 提供,支援 previous()、add()、set()、nextIndex()
  • 可逆向遍歷、修改、定位索引

五、專用容器深度解析

LinkedList — 棧/隊列/雙端隊列三合一

// 隊列操作
queue.offer(e);   // 入隊
queue.poll();     // 出隊
queue.peek();     // 查看隊首

// 棧操作
stack.push(e);
stack.pop();
stack.peek();

// 雙端隊列
deque.addFirst(e);
deque.addLast(e);

PriorityQueue — 優先級隊列

  • 元素按自然順序或Comparator排序
  • poll() 總是返回最高優先級元素
  • 適用:任務調度、訊息優先處理、A* 搜索算法

六、Collection vs Iterator 設計哲學

  • 實現 Collection = 完整容器契約(含 iterator())
  • 實現 Iterable = 僅支援 foreach 遍歷,**耦合度最低**
  • 外部類/第三方類無法修改繼承 → **提供 Iterator 適配器** 即可接入 foreach

適配器方法模式 — 為現有類添加遍歷方式

public class ReversibleArrayList extends ArrayList {
    public Iterable reversed() {
        return () -> new Iterator() {
            int current = size() - 1;
            public boolean hasNext() { return current >= 0; }
            public T next() { return get(current--); }
        };
    }
}
// 使用:for (T t : list.reversed()) { ... }

七、foreach 與 Iterable 關係

  • foreach 適用於:數組、**任何實現 Iterable 的對象**
  • 數組**不是** Iterable,編譯器特殊處理
  • 無自動裝箱發生,基本類型數組直接遍歷

八、實戰選型速查表

需求推薦容器備註
頻繁隨機訪問、末尾增刪ArrayList預設首選
頻繁頭尾/中間增刪LinkedList實現 Queue/Deque
去重、高速查找HashSet需正確實現 hashCode/equals
保持插入順序 + 去重LinkedHashSet插入序
排序、範圍查詢TreeSet實現 Comparable/Comparator
鍵值映射、高速查找HashMapKey 不可變對象最佳
Key 有序、範圍查詢TreeMap紅黑樹
LRU 快取、訪問順序LinkedHashMapaccessOrder=true
高併發映射ConcurrentHashMapJDK 8+ 無鎖擴容
優先級任務隊列PriorityQueue不可用於同步隊列
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved