java iterator报错主要有concurrentmodificationexception和nosuchelementexception两类:前者因遍历时直接修改集合结构触发fail-fast机制,应使用iterator.remove()或延后批量处理;后者因未校验hasnext()就调next()导致,须确保每次next前有hasnext判断。

Java 中 Iterator 迭代器报错,主要集中在两类:一是 ConcurrentModificationException(并发修改异常),二是 NoSuchElementException(无此元素异常)。它们成因明确、解决路径清晰,关键在于理解迭代器的 fail-fast 机制和调用规范。
ConcurrentModificationException:遍历时改集合结构
这是最典型的 Iterator 报错。只要在增强 for 循环或手动使用 Iterator 遍历过程中,直接调用集合自身的 add()、remove() 等方法修改结构,就会触发。
根本原因是:Iterator 内部维护一个 modCount 计数器,每次集合结构变更(增/删)都会更新它;而迭代器在每次 next() 前会校验当前 modCount 是否与初始值一致——不一致就立即抛异常,即 fail-fast(快速失败)。
✅ 正确做法:
- 遍历时删除元素,必须使用
iterator.remove(),而不是collection.remove() - 需要增/删多个元素,建议先收集待操作键/索引,遍历结束后统一处理(如用临时 List 存要删的元素,再调
removeAll()) - 对 Map 的
entrySet()遍历时,同样禁止直接调map.put()或map.remove(),应改用iterator.remove()或转为 Stream 过滤
NoSuchElementException:没检查 hasNext 就调 next
这个异常发生在调用 iterator.next() 时,迭代器已无后续元素(内部指针为 null),但代码未提前判断 hasNext()。
常见于手写 while 循环时漏写条件、或在循环体中多次调用 next() 导致跳过判断(例如一次循环里写了两次 it.next(),第二次可能越界)。
✅ 正确做法:
- 所有
next()调用前,必须包裹在if (it.hasNext())或while (it.hasNext())中 - 避免在一个循环迭代中多次调用
next();如需 key 和 value,应先存为变量:Map.Entry<k> e = it.next(); K k = e.getKey(); V v = e.getValue();</k> - 不要在遍历中途手动重置或重复使用已耗尽的迭代器(Iterator 不可复用)
其他易忽略的细节问题
有些报错看似无关,实则源于迭代器使用上下文错误:
-
HashMap 键值类型误用基本类型:如声明
HashMap<string int></string>会编译失败;必须用包装类Integer,否则自动装箱失效,后续取值可能为 null,引发 NPE -
多线程环境下未同步:即使单线程安全的 ArrayList,多线程遍历时也需外部同步,或改用
CopyOnWriteArrayList、ConcurrentHashMap等线程安全集合 -
遍历空集合未判空:虽然
iterator()返回空迭代器不会报错,但若逻辑依赖非空假设(如取首个元素),仍需先检查集合 size 或用 Optional 包装
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











