Iterator.remove()是遍历集合时安全删除当前元素的唯一方式,必须在next()后调用且不可连续调用;增强for循环中直接调用集合remove会抛ConcurrentModificationException;CopyOnWriteArrayList不支持remove();可改用收集待删元素再批量删除。

Java 中 Iterator.remove() 是唯一安全的、在遍历集合时删除当前元素的方式。直接调用集合自身的 remove()(如 list.remove())或在增强 for 循环中删除,会触发 ConcurrentModificationException。
必须配合 next() 使用
remove() 只能删除上一次 next() 返回的元素,且每个 next() 后最多调用一次 remove()。未调用 next() 就调用 remove(),或连续调用两次 remove(),都会抛出 IllegalStateException。
正确写法示例:
List<string> list = new ArrayList(Arrays.asList("a", "b", "c", "b"));
Iterator<string> it = list.iterator();
while (it.hasNext()) {
String s = it.next(); // 必须先 next()
if ("b".equals(s)) {
it.remove(); // 然后 remove 当前元素
}
}
// 结果:["a", "c"]
</string></string>
不能用于 foreach 循环
增强 for 循环(for (String s : list))底层隐式使用了迭代器,但不暴露引用,无法调用 remove()。此时若在循环体内调用 list.remove(),运行时必然报错。
错误示例:
for (String s : list) {
if ("b".equals(s)) {
list.remove(s); // ❌ 抛出 ConcurrentModificationException
}
}
应改写为显式 Iterator 循环,如上一节所示。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
不同集合的 remove 行为略有差异
虽然规范要求 remove() 删除上一个 next() 返回的元素,但具体实现可能有细微差别:
- ArrayList:删除后,后续元素前移,迭代器内部索引自动调整,不影响后续遍历。
- LinkedList:基于节点指针,删除操作不影响迭代器状态。
-
CopyOnWriteArrayList:其迭代器是快照式的,
remove()方法直接抛出UnsupportedOperationException—— 它不支持边遍历边修改。
使用前建议查阅对应集合类文档,确认是否支持 remove()。
替代方案:收集待删元素再批量删除
如果逻辑复杂、需多次判断或跨多个条件删除,可先用另一个集合暂存要删的元素,遍历结束后统一调用 removeAll():
List<string> toRemove = new ArrayList();
for (String s : list) {
if (shouldRemove(s)) {
toRemove.add(s);
}
}
list.removeAll(toRemove);
</string>
该方式更易读、不易出错,适合多条件、非顺序删除场景;缺点是额外内存开销,且对重复元素需注意语义(removeAll 按值匹配,会删掉所有匹配项)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










