Java ArrayList
ArrayList 是最常用的 List 實作,基於動態陣列,支援隨機存取。
建立 ArrayList
import java.util.ArrayList;
// 空的 ArrayList
ArrayList<String> list1 = new ArrayList<>();
// 指定初始容量
ArrayList<String> list2 = new ArrayList<>(100);
// 從其他集合建立
ArrayList<String> list3 = new ArrayList<>(Arrays.asList("A", "B", "C"));
// 使用 List 介面(推薦)
List<String> list4 = new ArrayList<>();
常用方法
新增元素
List<String> list = new ArrayList<>();
list.add("Apple"); // 加到尾端
list.add("Banana");
list.add(0, "First"); // 插入到指定位置
list.addAll(Arrays.asList("C", "D")); // 加入多個
存取元素
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
String first = list.get(0); // "A"
String last = list.get(list.size() - 1); // "C"
int index = list.indexOf("B"); // 1
int lastIndex = list.lastIndexOf("B");
修改元素
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
list.set(1, "X"); // 將索引 1 的元素改為 "X"
// ["A", "X", "C"]
刪除元素
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "B"));
list.remove(0); // 刪除索引 0 的元素
list.remove("B"); // 刪除第一個 "B"
list.clear(); // 清空
// 刪除多個
list.removeAll(Arrays.asList("A", "B"));
// 條件刪除
list.removeIf(s -> s.startsWith("A"));
檢查元素
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
boolean hasA = list.contains("A"); // true
boolean empty = list.isEmpty(); // false
int size = list.size(); // 3
遍歷
List<String> list = Arrays.asList("A", "B", "C");
// for 迴圈
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// for-each
for (String s : list) {
System.out.println(s);
}
// forEach + Lambda
list.forEach(s -> System.out.println(s));
list.forEach(System.out::println);
// Iterator
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
排序
List<Integer> numbers = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5));
// 升冪排序
Collections.sort(numbers);
// 或
numbers.sort(null);
// 或
numbers.sort(Comparator.naturalOrder());
// 降冪排序
Collections.sort(numbers, Collections.reverseOrder());
numbers.sort(Comparator.reverseOrder());
// 自訂排序
List<String> names = new ArrayList<>(Arrays.asList("Bob", "Alice", "Charlie"));
names.sort((a, b) -> a.length() - b.length()); // 依長度
轉換
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
// 轉為陣列
String[] array = list.toArray(new String[0]);
// 陣列轉 List
String[] arr = {"X", "Y", "Z"};
List<String> fromArray = new ArrayList<>(Arrays.asList(arr));
// 轉為 Stream
list.stream().filter(s -> s.equals("A")).collect(Collectors.toList());
子列表
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C", "D", "E"));
List<String> subList = list.subList(1, 4); // ["B", "C", "D"]
// 注意:subList 是原列表的視圖
subList.set(0, "X"); // list 也會改變
效能特性
| 操作 | 時間複雜度 |
|---|---|
| get(index) | O(1) |
| add(element) | O(1) 攤平 |
| add(index, element) | O(n) |
| remove(index) | O(n) |
| remove(element) | O(n) |
| contains(element) | O(n) |
ArrayList vs LinkedList
| 特性 | ArrayList | LinkedList |
|---|---|---|
| 隨機存取 | O(1) | O(n) |
| 尾端插入 | O(1) | O(1) |
| 中間插入 | O(n) | O(1) |
| 記憶體 | 較少 | 較多 |
一般情況下優先使用 ArrayList。
注意事項
避免在遍歷時修改
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
// 錯誤:ConcurrentModificationException
// for (String s : list) {
// list.remove(s);
// }
// 正確:使用 Iterator
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("B")) {
it.remove();
}
}
// 或使用 removeIf
list.removeIf(s -> s.equals("B"));
泛型
// 不建議:原始類型
ArrayList list = new ArrayList();
// 建議:使用泛型
ArrayList<String> list = new ArrayList<>();