List 介面核心定位
- 繼承
Collection,表示有序、可重複、可為 null的元素序列
- 核心特性:精確位置控制(索引訪問)、允許重複元素、允許多個 null
- 提供位置相關操作:
get(index)、add(index, e)、remove(index)、set(index, e)、indexOf/lastIndexOf
- 專用迭代器:
ListIterator(雙向遍歷、可修改、可獲取索引)
四大主流實現類對比
| 實現類 | 底層結構 | 線程安全 | 核心優勢 | 核心劣勢 | 適用場景 |
| ArrayList | 動態陣列 | 否 | 隨機訪問 O(1)、記憶體緊湊、遍歷極快 | 頭部/中間增刪 O(n) | 默認首選 (90%+ 場景) |
| LinkedList | 雙向鏈表 | 否 | 首尾增刪 O(1)、實現 Deque/Queue/Stack | 隨機訪問 O(n)、記憶體開銷大 | 高頻頭尾操作、棧/隊列/雙端隊列 |
| Vector | 動態陣列 | 是 (方法級同步) | 舊代碼兼容、可配置擴容增量 | 同步開銷大、API 陳舊 | 極舊版本維護,新代碼禁用 |
| Stack | 繼承 Vector | 是 | LIFO 棧語義 API | 繼承 Vector 包袱、功能單一 | 教學/舊代碼,新代碼用 ArrayDeque |
List 核心 API 全景速查
| 分類 | 關鍵方法 | 說明 |
| 位置操作 | get(int index) | 返回指定位置元素 |
set(int index, E element) | 替換指定位置元素 |
add(int index, E element) | 插入元素,後續右移 |
remove(int index) | 移除並返回指定位置元素 |
addAll(int index, Collection<? extends E> c) | 批量插入集合 |
| 查找 | indexOf(Object o) | 首次出現索引,無則 -1 |
lastIndexOf(Object o) | 末次出現索引 |
contains(Object o) | 是否包含元素 |
containsAll(Collection<?> c) | 是否包含所有元素 |
| 批量修改 | removeAll(Collection<?> c) | 移除所有包含在 c 中的元素 |
retainAll(Collection<?> c) | 僅保留包含在 c 中的元素 (交集) |
clear() | 清空列表 |
subList(int from, int to) | 返回視圖 [from, to),修改影響原列表 |
| 迭代器 | iterator() | 單向 Iterator |
listIterator() | 雙向 ListIterator (可獲取索引、add/set/remove) |
listIterator(int index) | 從指定索引開始的 ListIterator |
| 轉換 | toArray() | 返回 Object[] |
toArray(T[] a) | 返回類型安全數組 (推薦 new Type[0]) |
ListIterator 進階用法
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
ListIterator<String> it = list.listIterator();
// 正向遍歷
while (it.hasNext()) {
int idx = it.nextIndex();
String val = it.next();
if ("b".equals(val)) it.set("B"); // 修改
}
// 逆向遍歷
while (it.hasPrevious()) {
int idx = it.previousIndex();
String val = it.previous();
if ("a".equals(val)) it.add("new"); // 在前插入
}
現代替代方案:多執行緒場景選型
| 場景 | 推薦方案 | 特性 |
| 讀多寫少、需快照隔離 | CopyOnWriteArrayList | 寫入複製數組、讀無鎖、迭代器不拋 CME |
| 高並發讀寫、需複合操作原子 | Collections.synchronizedList + 手動鎖 | 粗粒度鎖、複合操作需 synchronized(list) |
| 棧/隊列/雙端隊列語義 | ArrayDeque / ConcurrentLinkedDeque | 高效雙端操作、非同步/並發版 |
| 單執行緒、高效能 | ArrayList / LinkedList | 無同步開銷、按訪問模式選擇 |
避坑指南精華版
- ✅ 默認 new ArrayList<>(預估大小),減少擴容。
- ✅ 需首尾高頻操作用 LinkedList,或直接用 ArrayDeque。
- ❌ 不要在 for-each/Iterator 中直接 list.remove(),用 Iterator.remove() 或 removeIf()。
- ❌ 循環添加對象必須每次 new,否則全是同一引用。
- ❌ 多執行緒勿直接用 ArrayList/LinkedList/Vector,選並發集合。
- ✅ toArray 必須傳類型陣列:
list.toArray(new String[0])。
- ✅ 善用 subList 視圖處理區間,但注意結構修改會失效。
總結
List 是 Java 處理有序集合的核心抽象。ArrayList 是默認王者,LinkedList 專治首尾操作,Vector/Stack 是歷史包袱。掌握位置操作、雙向迭代器、實現類效能特性、多執行緒替代方案、經典陷阱,是 Java 開發者從入門到精通的必經之路。選對工具,事半功倍。