List<ForTest> list = new ArrayList<>();
list.add(new ForTest("1")); // index 0
list.add(new ForTest("2")); // 1
list.add(new ForTest("3")); // 2
list.add(new ForTest("4")); // 3
list.add(new ForTest("5")); // 4
// ... 共 7 個元素
for (int i = 0; i < list.size(); i++) {
ForTest test = list.get(i);
if (test.getFlag().equals("3")) {
list.remove(i); // 刪除 index 2 ("3")
}
System.out.println("循環到:" + i + ", flag=" + test.getFlag());
}
輸出:
循環到:0, flag=1 循環到:1, flag=2 循環到:2, flag=3 <-- 刪除 "3" 循環到:3, flag=5 <-- 本意應為 "4",實際打印 "5"! 循環到:4, flag=6 循環到:5, flag=7
結果:元素 "4" 被跳過,"5" 移到了 index 3 被打印。
for (int i = list.size() - 1; i >= 0; i--) {
if (list.get(i).getFlag().equals("3")) {
list.remove(i); // 刪除後,較小索引元素不受影響
}
}
Iterator<ForTest> it = list.iterator();
while (it.hasNext()) {
ForTest test = it.next();
if (test.getFlag().equals("3")) {
it.remove(); // 安全刪除,不拋 ConcurrentModificationException
}
}
list = list.stream()
.filter(t -> !t.getFlag().equals("3"))
.collect(Collectors.toList());
注意:此法生成新列表,原列表引用改變,若有其他引用持有舊列表需謹慎。
| 方法 | 時間複雜度 | 空間 | 適用場景 |
|---|---|---|---|
| 逆序 for | O(n) | O(1) | ArrayList、LinkedList 通用,就地修改 |
| Iterator | O(n) | O(1) | 所有 List 實現,標準 API |
| Stream filter | O(n) | O(n) | 需保留原列表、鏈式操作、並行流 |
ConcurrentModificationExceptionlist.removeIf(t -> t.getFlag().equals("3"));
內部實現即為 Iterator 遍歷刪除,簡潔高效,推薦作為首選。