Collections Framework 的核心在於「介面與實現分離」。本文系統梳理三大實現類別——通用、包裝器、便利實現,並深度剖析通用實現的選型邏輯與效能特徵。
| 類別 | 特徵 |
|---|---|
| 通用實現 | 公共類,核心介面主要實現(HashSet, ArrayList, HashMap 等) |
| 包裝器實現 | 委託現有集合,疊加功能(同步、不可變),對應 Decorator 模式 |
| 便利實現 | 小型專用實現,透過靜態工廠方法獲取(singleton, nCopies 等) |
命名模式:<資料結構><介面>,如 HashSet(雜湊表 + Set)、TreeMap(紅黑樹 + Map)。
| 介面 | 雜湊表 | 可調整陣列 | 平衡樹 | 連結串列 |
|---|---|---|---|---|
| Set | HashSet | — | TreeSet | — |
| List | — | ArrayList | — | LinkedList |
| Map | HashMap | — | TreeMap | — |
主實現:HashSet、ArrayList、HashMap(SortedSet/Map 僅有 TreeSet/TreeMap)。
null 元素、鍵、值clone設計哲學:不為不必要的同步付費;單線程、唯讀、大型同步物件內部使用時同步純屬浪費,甚至引發死鎖。需同步時用包裝器:Collections.synchronizedXxx。
// 推薦:宣告型別為介面
List<String> list = new ArrayList<>();
Set<String> set = new HashSet<>();
Map<String, String> map = new HashMap<>();
僅在建構時指定實現,後續完全面向介面,保留隨時切換實現的彈性。
| 實現 | 時間複雜度 | 順序保證 | 適用場景 |
|---|---|---|---|
| HashSet | O(1) 平均 | 無序 | 預設首選,效能最佳 |
| TreeSet | O(log n) | 自然順序/Comparator | 需排序操作或有序迭代 |
HashSet 調參:初始容量預設 16,負載因子 0.75。迭代耗時與「容量+元素數」成正比,若迭代頻繁請適度設定初始容量(約預期元素數 2 倍)。
| 實現 | 隨機存取 | 頭部插入/刪除 | 記憶體開銷 | 建議 |
|---|---|---|---|---|
| ArrayList | O(1) | O(n) | 低(無節點物件) | 90% 場景首選 |
| LinkedList | O(n) | O(1) | 高(雙向節點) | 頻繁頭部操作或中間刪除 |
ArrayList 可視為無同步開銷的 Vector。LinkedList 提供 addFirst/getFirst/removeFirst 等 6 個雙端佇列操作,但常數因子極大,**務必實測比較**後再決定。
固定大小列表請用 Arrays.asList(便利實現),效能最高。
HashMap:預設首選,O(1) 平均TreeMap:需 SortedMap 操作或有序視圖迭代舊版 Hashtable、Vector 同步版本稍快於包裝器,但背負 Legacy API 包袱,**嚴禁直接操作具體類**,必須面向 Map/List 介面。
漸近複雜度(constant, log, linear, n log n, quadratic)僅為理論上界。實際資料量小、常數因子差異大時,「理論較慢」的實現可能更快。**有疑慮請實測**。
掌握通用實現的特性與選型邏輯,是寫出高效、可維護 Java 代碼的基石。