List 四大主力 — ArrayList、LinkedList、Vector、Stack — 底層結構差異導致截然不同的效能特徵。本文剖析八大維度,揭示「隨機存取用 ArrayList、頻繁增刪用 LinkedList」背後的資料結構原理,並給出轉換策略、同步處理、不可修改視圖等實戰技巧。
| 實現 | 結構 | 隨機存取 | 中間增刪 | 記憶體開銷 |
|---|---|---|---|---|
| ArrayList | 動態陣列 | O(1) 極快 | O(N) 需搬移 | 低 (連續記憶體) |
| Vector | 動態陣列 (同步) | O(1) | O(N) | 低 |
| LinkedList | 雙向鏈表 | O(N) 需遍歷 | O(1) 僅改指標 | 高 (節點額外指標) |
| Stack | 繼承 Vector (陣列) | O(1) | 僅支援棧頂操作 | 低 |
push/pop/peek,繼承 Vector 故同步Deque,可作**棧**、**隊列**、**雙端隊列** (addFirst/last, pollFirst/last)System.arraycopy 複製,舊陣列成垃圾 → GC 壓力synchronized),但複合操作仍需外部同步 (如檢查大小後取元素)Collections.synchronizedList(list) 包裝或用 CopyOnWriteArrayList (讀多寫少)ConcurrentModificationException場景 A:資料量未知,從 DB 讀出後幾乎只讀遍歷 → 先 LinkedList 累積,再轉 ArrayList 優化遍歷**
List<Row> temp = new LinkedList<>();
while (rs.next()) temp.add(mapRow(rs));
List<Row> fastList = new ArrayList<>(temp); // 一次性複製,後續極速遍歷
場景 B:資料量固定,需頻繁中間增刪 → ArrayList → LinkedList**
List<Item> list = new ArrayList<>(initialData);
// 需大量增刪時
list = new LinkedList<>(list); // 轉換成本 O(N),後續增刪 O(1)
轉換本質:建構子複製元素引用,new ArrayList(linkedList) / new LinkedList(arrayList)
System.arraycopy 直接複製底層陣列 → 極快
List<T> unmodifiable = Collections.unmodifiableList(list);
// 任何修改 (含迭代器 remove) 拋 UnsupportedOperationException
it.remove())hasPrevious/previous)、可修改/新增指定位置java.util.Collections 提供排序 (sort)、二分搜 (binarySearch)、反轉 (reverse)、填充 (fill)、同步包裝、不可修改視圖、單例集合等豐富靜態方法,避免重複造輪子。