集合框架核心介面架構
Collection (介面)
├── List (有序、可重複)
│ ├── ArrayList (動態陣列,查詢快)
│ ├── LinkedList (雙向鏈表,增刪快)
│ └── Vector (同步,舊版遺留)
└── Set (無序、不可重複)
├── HashSet (雜湊表,O(1) 查詢)
├── LinkedHashSet (鏈表+雜湊,保持插入序)
└── TreeSet (紅黑樹,有序、O(log n))
Map (介面,鍵值對)
├── HashMap (雜湊表,通用首選)
├── LinkedHashMap (保持插入/存取序)
├── TreeMap (紅黑樹,Key 有序)
├── Hashtable (同步,舊版遺留)
└── ConcurrentHashMap (高併發首選)
三大核心介面特徵對比
| 介面 | 有序性 | 重複性 | 典型實作 | 核心用途 |
| List | ✅ 插入序 | ✅ 允許重複 | ArrayList, LinkedList | 有序清單、索引存取、佇列/棧 |
| Set | ❌ (除 LinkedHash/Tree) | ❌ 唯一 | HashSet, TreeSet | 去重、集合運算 (交/並/差)、唯一性檢查 |
| Map | ❌ (除 LinkedHash/Tree) | Key 唯一,Value 可重複 | HashMap, TreeMap | 鍵值映射、快取、索引、分組統計 |
主流實作選型指南
List 選型
- ArrayList:預設首選。隨機存取 O(1),尾部增刪攤還 O(1),中間增刪 O(n)。記憶體緊湊。
- LinkedList:頻繁頭部/中間增刪、實作 Queue/Deque 時。隨機存取 O(n),記憶體開銷大 (節點物件)。
- Vector:棄用。同步開銷大,單執行緒用 ArrayList,多執行緒用
Collections.synchronizedList 或 CopyOnWriteArrayList。
Set 選型
- HashSet:預設首選。O(1) 含有判斷,無序。
- LinkedHashSet:需保持插入順序遍歷。稍大記憶體。
- TreeSet:需自然序/自訂序遍歷、範圍查詢 (
subSet, headSet)。O(log n)。
Map 選型
- HashMap:預設首選。O(1) 存取。
- LinkedHashMap:需保持插入順序 (LRU 快取利器
removeEldestEntry)。
- TreeMap:需 Key 排序、範圍查詢。
- Hashtable:棄用。全鎖同步,效能差。改用 ConcurrentHashMap。
- ConcurrentHashMap:高併發讀寫首選。JDK 8+ CAS + synchronized + 紅黑樹。
遍歷方式總結
| 方式 | 適用對象 | 優點 | 缺點 |
| for-each (增強 for) | Collection, Map (entrySet/keySet/values) | 簡潔、唯讀安全 | 無法移除元素、無索引 |
| Iterator | Collection | 可安全移除 (iterator.remove()) | 語法較繁瑣 |
| ListIterator | List | 雙向、可修改、可獲取索引 | 僅 List 可用 |
| forEach (Lambda) | Collection, Map | 函數式、可並行 (parallelStream) | 除錯較難、檢查型異常處理繁瑣 |
| 傳統 for (索引) | List, Array | 完全控制、可修改結構 | 冗長、易越界 |
Map 遍歷最佳實踐
// 推薦:entrySet (單次查找 Key+Value)
for (Map.Entry entry : map.entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
}
// 避免:keySet + get (雙重查找)
for (K key : map.keySet()) {
V value = map.get(key); // 額外 hash 查找
}
// Java 8+ Lambda
map.forEach((k, v) -> System.out.println(k + "=" + v));
常見操作複雜度速查 (平均情況)
| 操作 | ArrayList | LinkedList | HashSet | TreeSet | HashMap | TreeMap |
| get(index/key) | O(1) | O(n) | - | - | O(1) | O(log n) |
| add(element) | O(1)* | O(1) | O(1) | O(log n) | O(1) | O(log n) |
| remove(index/key) | O(n) | O(n) | O(1) | O(log n) | O(1) | O(log n) |
| contains | O(n) | O(n) | O(1) | O(log n) | O(1) | O(log n) |
| iterator 遍歷 | O(n) | O(n) | O(n) | O(n) | O(n) | O(n) |
* 攤還常數時間,擴容時為 O(n)
新手必記黃金法則
- 面向介面宣告:
List<String> list = new ArrayList<>(); 而非 ArrayList<String> list = new ArrayList<>();
- 指定泛型:
new ArrayList<String>() 而非 new ArrayList()
- 預估初始容量:
new ArrayList<>(expectedSize) 減少擴容複製
- 不可變集合:Java 9+
List.of(), Set.of(), Map.of() 建立唯讀集合
- 並發安全:多執行緒寫入必須用 Concurrent 類或同步包裝,
Collections.synchronizedList 僅方法級同步,複合操作仍需外部鎖
- 上一篇文章: Java 冒泡排序基礎實作:標準演算法邏輯與程式碼範例
- 下一篇文章: 《深入理解 Java 虛擬機》閱讀筆記:JVM 體系架構、類載入、執行引擎與運行時資料區
Copyright ©
程式碼之家 All Rights Reserved