ArrayList 是一個動態陣列實作的 List 介面,繼承自 AbstractList,實作了 RandomAccess、Cloneable、Serializable 介面。相較於傳統陣列,它的容量可隨元素新增自動擴充。支援快速隨機存取(索引查詢)、元素新增、刪除、修改、遍歷等操作。
RandomAccess,透過索引 get(index) 為 O(1) 時間複雜度Vector 或 CopyOnWriteArrayList(舊容量 × 3) / 2 + 1

ArrayList() // 預設容量 10
ArrayList(int capacity) // 指定初始容量
ArrayList(Collection<? extends E> c) // 從集合建立
Collection 介面方法:add、addAll、clear、contains、size、toArray 等
List 介面方法:add(index, element)、get(index)、set(index, element)、remove(index)、subList 等
ArrayList 專有方法:ensureCapacity、trimToSize、removeRange、clone
private transient Object[] elementData; // 儲存元素的陣列
private int size; // 實際元素數量
擴容 ensureCapacity:檢查容量,不足時建立新陣列並 Arrays.copyOf 複製
新增元素 add:確保容量後,直接 elementData[size++] = e
指定位置插入 add(index, element):System.arraycopy 將 index 後元素右移,再插入
刪除元素 remove:System.arraycopy 將後續元素左移,最後一位設 null 利於 GC
隨機存取 get:RangeCheck 後直接回傳 elementData[index],O(1) 效能
| 遍歷方式 | 程式碼範例 | 耗時 (10萬筆) |
|---|---|---|
| 隨機存取 (for + get) | for (int i=0; i<size; i++) list.get(i) | 3 ms |
| for-each 迴圈 | for (Integer v : list) ... | 5 ms |
| Iterator 迭代器 | while (iter.hasNext()) iter.next() | 8 ms |
結論:ArrayList 因實作 RandomAccess,索引遍歷最快;迭代器有額外開銷,效能最低。
toArray() 回傳 Object[],強轉為 String[] 會拋 ClassCastException。正確做法:
// 方式一:預先配置大小
String[] arr = new String[list.size()];
list.toArray(arr);
// 方式二:傳入空陣列 (最常用、效能佳)
String[] arr = list.toArray(new String[0]);
ArrayList<String> list = new ArrayList<>();
list.add("1"); list.add("2"); list.add("3");
list.add(0, "5"); // 指定位置插入
System.out.println(list.get(0)); // 5
list.remove("3"); // 刪除指定元素
list.set(1, "10"); // 修改元素
// 遍歷輸出
for (String s : list) System.out.println(s);
// 轉陣列
String[] arr = list.toArray(new String[0]);