在 Java 開發與面試中,ArrayList、Vector 與 LinkedList 的比較幾乎是必考題目。這三者皆實作 List 介面,擁有有序、可重複的特性,但底層資料結構、執行緒安全性與效能表現截然不同。本文將從原理、效能、適用場景三個維度,為你徹底釐清三者的差異與選型策略。
| 特性 | ArrayList | Vector | LinkedList |
|---|---|---|---|
| 底層結構 | 動態陣列 | 動態陣列 | 雙向鏈結串列 |
| 執行緒安全 | 非同步(Not Thread-safe) | 同步 | 非同步 |
| 擴容機制 | 1.5 倍 | 2 倍 | 無擴容概念,節點動態分配 |
| 隨機存取 | 快 | 快 | 慢(需遍歷) |
| 插入/刪除 | 慢(需位移元素) | 慢 | 快(僅修改指標) |
| 記憶體開銷 | 低 | 低 | 高(每節點額外儲存前後指標) |
ArrayList 內部封裝一個 Object[] 陣列。其優勢在於 O(1) 的隨機存取速度(get(index)、set(index, e))。然而,在中間位置插入或刪除元素時,需透過 System.arraycopy 位移後續元素,時間複雜度為 O(n)。預設初始容量為 10,擴容時增長為原容量的 1.5 倍。
適用場景: 讀多寫少、頻繁隨機存取、單執行緒環境或外部同步控制。
Vector 是 JDK 1.0 就存在的「老前輩」,方法層面加了 synchronized 關鍵字,確保執行緒安全。但這帶來顯著的效能開銷。擴容策略為翻倍(2 倍),且保留了 Enumeration 介面等過時 API。現代開發中,若需執行緒安全的 List,推薦使用 Collections.synchronizedList(new ArrayList<>()) 或並發包下的 CopyOnWriteArrayList。
注意: 疊代器為 fail-fast 機制,並發修改會拋出 ConcurrentModificationException。
LinkedList 採用雙向鏈結串列,每個節點包含 prev、next 指標與資料。優勢在於頭尾增刪為 O(1),適合實作堆疊、佇列、雙端佇列。劣勢是隨機存取需遍歷,平均 O(n/2);且每個元素額外佔用兩個指標記憶體,GC 壓力較大。
適用場景: 頻繁在頭尾或中間插入刪除、作為 Queue/Deque 使用、資料量不極大時。
Collection
└─ List
├─ ArrayList
├─ LinkedList
├─ Vector
│ └─ Stack
└─ ...
CopyOnWriteArrayList(讀多寫少)或 Collections.synchronizedList。ArrayList(預設首選)。LinkedList。T[]。List<T> list = new ArrayList<>();,方便日後替換實作。new ArrayList<>(initialCapacity) 避免多次擴容複製。Vector 或同步包裝,將同步塊拉到迴圈外層,減少鎖開銷。ArrayList 大量刪除前可呼叫 ensureCapacity 或改用 LinkedList。沒有完美的集合,只有最適合場景的選擇。理解底層資料結構(陣列 vs 鏈結串列)與同步機制,才能在效能與正確性間取得平衡。日常開發中,ArrayList 覆蓋 80% 以上場景;LinkedList 專注佇列與頻繁增刪;Vector 則退居教學與維護舊代碼的歷史舞台。