在 java 中,使用 iterator 遍历集合时直接修改集合元素本身不会抛出异常,但如果试图通过 iterator 的 remove() 方法移除元素,必须确保是在调用 next() 之后进行的,否则会在下一次迭代时抛出 illegalstateexception。正确的做法是获取 iterator 实例后,在循环体内先调用 next() 获取当前元素,随后根据条件判断是否调用 remove() 来安全地删除该元素。

Iterator 遍历时移除元素的正确时机是什么
必须在调用 next() 之后才能调用 remove()。这是因为 Iterator 内部维护了一个游标状态,只有成功获取了下一个元素后,才允许移除该元素。如果在没有调用 next() 的情况下直接调用 remove(),或者在调用 remove() 后又立即再次调用 remove(),都会触发 IllegalStateException。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String item = it.next(); // 必须先调用 next()
if (item.equals("B")) {
it.remove(); // 此时移除是安全的
}
}
System.out.println(list); // 输出 [A, C]
}
}
为什么不能在增强 for 循环中直接移除元素
增强 for 循环(foreach)底层依赖于 Iterator,但它隐藏了 next() 和 remove() 的显式调用过程。当你在增强 for 循环中直接调用集合的 remove() 方法时,会破坏 Iterator 的内部状态,导致在下次迭代检查时抛出 ConcurrentModificationException。因此,如果需要边遍历边删除,必须手动获取 Iterator 并显式控制流程。
你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型
立即学习“Java免费学习笔记(深入)”;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
// 错误示范:增强 for 循环中直接 remove
// for (String item : list) {
// if (item.equals("B")) {
// list.remove(item); // 抛出 ConcurrentModificationException
// }
// }
// 正确做法:使用 Iterator
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("B")) {
it.remove();
}
}
System.out.println(list);
}
}
如果需要在遍历过程中替换元素而不是移除怎么办
Iterator 接口并没有提供直接替换元素的方法。如果你需要修改元素的内容,可以通过 next() 获取引用后直接修改对象属性(对于可变对象),或者使用索引遍历的方式配合 set() 方法(仅适用于支持随机访问的列表如 ArrayList)。对于不可变对象或需要替换整个引用的场景,建议收集待替换项,遍历结束后再统一处理,或使用 ListIterator 的 set() 方法。

















