Java 編程思想 (第 4 版) 學習筆記:第 11 章 容器打印輸出與 Collection/Map 體系總覽
本文基於《Java 編程思想》第 11 章「容器」節選,展示各類容器 toString() 輸出格式差異,並系統梳理 Java 容器類體系:Collection 介面下的 List/Set/Queue 及 Map 介面下的主要實現類特點與選型指南。
一、容器打印輸出實戰代碼與結果
import java.util.*;
public class ContainerPrintDemo {
static Collection<String> fill(Collection<String> c) {
c.add("rat"); c.add("cat"); c.add("dog"); c.add("dog"); // 重複元素
return c;
}
static Map<String, String> fill(Map<String, String> m) {
m.put("rat", "Fuzzy"); m.put("cat", "Rags");
m.put("dog", "Bosco"); m.put("dog", "Spot"); // 重複鍵,後覆蓋前
return m;
}
public static void main(String[] args) {
// Collection 系:方括號 []、逗號分隔、元素 toString()
System.out.println("ArrayList: " + fill(new ArrayList<>()));
System.out.println("LinkedList: " + fill(new LinkedList<>()));
System.out.println("HashSet: " + fill(new HashSet<>()));
System.out.println("TreeSet: " + fill(new TreeSet<>()));
System.out.println("LinkedHashSet:" + fill(new LinkedHashSet<>()));
// Map 系:大括號 {}、鍵=值、逗號分隔
System.out.println("HashMap: " + fill(new HashMap<>()));
System.out.println("TreeMap: " + fill(new TreeMap<>()));
System.out.println("LinkedHashMap:" + fill(new LinkedHashMap<>()));
}
}
執行輸出結果
ArrayList: [rat, cat, dog, dog]
LinkedList: [rat, cat, dog, dog]
HashSet: [cat, dog, rat]
TreeSet: [cat, dog, rat]
LinkedHashSet:[rat, cat, dog]
HashMap: {cat=Rags, dog=Spot, rat=Fuzzy}
TreeMap: {cat=Rags, dog=Spot, rat=Fuzzy}
LinkedHashMap:{rat=Fuzzy, cat=Rags, dog=Spot}
輸出特徵解讀
- Collection:
AbstractCollection.toString() 統一格式 [e1, e2, ...]。
- List (ArrayList/LinkedList):保留插入順序、**允許重複**。
- HashSet:無序、**去重** (hashCode/equals)。
- TreeSet:自然順序排序 (Comparable)、**去重**。
- LinkedHashSet:插入順序、**去重** (雙向鏈表維護順序)。
- Map:
AbstractMap.toString() 統一格式 {k1=v1, k2=v2, ...}。
- HashMap:無序、鍵唯一 (後插入覆蓋)。
- TreeMap:鍵自然順序排序。**注意**:輸出按鍵字母序
cat, dog, rat。
- LinkedHashMap:插入順序 (或存取順序
accessOrder=true)。
二、Java 容器類體系全景圖
Collection 介面三大支柱
| 介面 | 核心特徵 | 主要實現 | 適用場景 |
| List | 有序、可重複、支援索引隨機存取 | ArrayList (動態陣列)、LinkedList (雙向鏈表)、Vector (同步、舊) | 需按索引存取、頻繁尾部增刪 → ArrayList;頻繁頭部/中間增刪 → LinkedList |
| Set | 無重複、最多一個 null | HashSet (HashMap 底層)、TreeSet (紅黑樹)、LinkedHashSet (雙向鏈表+HashMap) | 去重、集合運算 (交/並/差) → HashSet;需排序 → TreeSet;需插入順序 → LinkedHashSet |
| Queue | FIFO (或優先級)、雙端 | PriorityQueue (堆)、ArrayDeque (雙端陣列)、LinkedList (也實現 Deque) | 任務排程 → PriorityQueue;高效雙端隊列/棧 → ArrayDeque |
Map 介面三大主力
| 實現 | 底層結構 | 順序 | Null 鍵/值 | 線程安全 | 選型建議 |
| HashMap | 陣列+鏈表/紅黑樹 (JDK 8+) | 無序 | 允許 1 個 null key、多 null value | 否 | 通用首選,JDK 8+ 高併發效能優化 |
| TreeMap | 紅黑樹 | 鍵自然序/Comparator 排序 | 不允許 null key | 否 | 需有序遍歷、範圍查詢 (subMap) |
| LinkedHashMap | HashMap + 雙向鏈表 | 插入序/存取序 | 允許 null | 否 | 需可預測迭代順序、LRU 快取 (override removeEldestEntry) |
| Hashtable | 陣列+鏈表 | 無序 | 不允許 null | 是 (synchronized) | 舊 API,**不推薦**,併發用 ConcurrentHashMap |
| ConcurrentHashMap | CAS + synchronized (JDK 8+ 分段鎖移除) | 無序 | 不允許 null | 是 (高併發) | 多執行緒環境首選 |
三、核心實現類效能特徵速查
- ArrayList:隨機存取 O(1)、尾部增刪均攤 O(1)、中間增刪 O(n) (需搬移)、擴容 1.5x。
- LinkedList:頭尾增刪 O(1)、索引存取 O(n) (需遍歷)、記憶體開銷大 (節點物件)、實現 Deque/Queue。
- HashSet/HashMap:增刪查 O(1) 平均、負載因子 0.75、JDK 8 鏈表轉紅黑樹 (閾值 8) 防退化。
- TreeSet/TreeMap:增刪查 O(log n)、紅黑樹自平衡、支援
first()/last()/subSet() 範圍操作。
- PriorityQueue:最小堆、插入/取最小 O(log n)、無序迭代、非線程安全。
- ArrayDeque:循環陣列、雙端 O(1)、無容量上限 (自動擴容)、比 LinkedList 快、非線程安全。
四、選型決策樹 (簡化版)
需要鍵值對嗎?
├─ 是 → Map
│ ├─ 多執行緒? → ConcurrentHashMap
│ ├─ 需排序/範圍查詢? → TreeMap
│ ├─ 需插入/存取順序? → LinkedHashMap
│ └─ 通用 → HashMap
└─ 否 → Collection
├─ 需索引隨機存取? → ArrayList
├─ 需雙端隊列/棧? → ArrayDeque
├─ 需優先級隊列? → PriorityQueue
├─ 需去重?
│ ├─ 需排序? → TreeSet
│ ├─ 需插入順序? → LinkedHashSet
│ └─ 通用 → HashSet
└─ 允許重複、頻繁中間增刪? → LinkedList
否 → ArrayList