最推荐使用 removeIf() 方法。它语义清晰、一行解决、底层用迭代器实现,自动避免 ConcurrentModificationException,且性能良好;其次可选迭代器 remove()、倒序 for 循环或收集后批量删除。

在 Java 中,直接用 for 循环遍历 ArrayList 并调用 remove() 删除指定元素,很容易出现 漏删、越界或 ConcurrentModificationException。关键是要避开“边遍历边修改”的陷阱,选对删除方式。
用迭代器(Iterator)的 remove() 方法
这是最标准、最安全的遍历中删除方式。迭代器的 remove() 是专为“边遍历边删”设计的,它会自动维护内部游标状态,不会导致索引错乱或异常。
- 必须在
next()调用之后调用remove(),否则抛IllegalStateException - 每次只能删一个元素(即刚
next()返回的那个) - 不能和集合自身的
remove()混用,否则仍可能触发ConcurrentModificationException
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
if ("target".equals(s)) {
it.remove(); // ✅ 安全删除
}
}倒序 for 循环(从 size-1 到 0)
正向循环删除时,后面元素前移会导致跳过下一个元素;而倒序删除,前面元素不受影响,索引不会“失效”。
- 适用于已知要删哪些元素(比如按值或条件),且不需要保留原始顺序的场景
- 注意循环变量是
i--,终止条件是i >= 0 - 删除后无需调整索引,因为只影响后面的项,而你已不再访问它们
for (int i = list.size() - 1; i >= 0; i--) {
if ("target".equals(list.get(i))) {
list.remove(i); // ✅ 安全,i 不会越界
}
}收集待删元素,再批量移除
先遍历一次,把所有匹配的元素(或对应索引)存进临时集合,遍历完再统一删。适合需要多次判断、逻辑较复杂的情况。
立即学习“Java免费学习笔记(深入)”;
- 推荐用
removeAll(Collection)批量删除,效率比逐个删高 - 若按索引删,可用
list.removeAll(indices.stream().mapToObj(list::get).collect(Collectors.toList())),但更推荐直接存元素值 - 注意:如果元素重复,
removeAll会删掉所有匹配项(符合多数预期)
List<String> toRemove = new ArrayList<>();
for (String s : list) {
if (s.startsWith("tmp_")) {
toRemove.add(s);
}
}
list.removeAll(toRemove); // ✅ 一次清理,线程安全(单线程下)Java 8+ 推荐:removeIf() 一行解决
Collection.removeIf(Predicate) 是最简洁安全的方式,底层使用迭代器实现,自动处理并发修改问题。
- 语义清晰:“删掉所有满足条件的元素”
- 无需手动管理迭代器或索引,不易出错
- 性能良好,且是 JDK 原生支持的线程安全(单线程操作下)
list.removeIf(s -> "target".equals(s)); // ✅ 最推荐,一行搞定 list.removeIf(s -> s == null || s.trim().isEmpty());


















