java中iterator不存在“迭代越界”,常见错误是未校验hasnext()就调用next()抛nosuchelementexception,或遍历时非法修改集合触发concurrentmodificationexception。

Java 中 Iterator 迭代器本身不会出现“迭代越界”这种说法——它没有索引、不支持随机访问,也就不存在 index >= size 的越界概念。真正容易出错的,是错误地在 hasNext() 为 false 时还调用 next(),这会直接抛出 NoSuchElementException。
所以所谓“排查迭代越界问题”,本质是排查 next() 调用前未校验 hasNext(),或在遍历中途非法修改集合导致 fail-fast 异常这两类典型问题。
? 如何快速定位和排查
✅ 1. 检查是否跳过 hasNext() 直接调用 next()
这是最常见、最直接的报错源头。
-
错误写法(危险!):
Iterator<string> it = list.iterator(); String s = it.next(); // ❌ 未判断就取值!空集合时立刻抛 NoSuchElementException</string>
-
正确写法(必须配对):
Iterator<string> it = list.iterator(); while (it.hasNext()) { // ✅ 先判断 String s = it.next(); // ✅ 再取值 System.out.println(s); }</string>
⚠️ 注意:
next()是“消费式”操作——每次调用都推进指针。不能反复调用next()而不检查hasNext(),否则第二次调用可能已无元素。
✅ 2. 检查是否在遍历时用集合自身方法增删元素
Iterator 的 remove() 是唯一安全的删除方式;若用 list.remove(obj) 或 list.add(...),会触发 ConcurrentModificationException。
-
错误示例:
for (Iterator<string> it = list.iterator(); it.hasNext(); ) { String s = it.next(); if ("Python".equals(s)) { list.remove(s); // ❌ 非迭代器方式删除 → 抛 ConcurrentModificationException } }</string> -
正确做法:
Iterator<string> it = list.iterator(); while (it.hasNext()) { String s = it.next(); if ("Python".equals(s)) { it.remove(); // ✅ 唯一推荐的遍历中删除方式 } }</string>
? 提示:
it.remove()只能删除上一次next()返回的元素,且每调用一次next()后最多调用一次remove(),重复调用会抛IllegalStateException。
✅ 3. 检查是否多线程并发修改
单线程下 ConcurrentModificationException 多因“自己改了自己”;多线程下更易触发——哪怕只是两个线程一个读(迭代)、一个写(add/remove),也会失败。
- 排查建议:
- 查看堆栈中异常是否带
ConcurrentModificationException - 确认该集合是否被多个线程共享且未加锁或未使用线程安全替代品(如
CopyOnWriteArrayList、Collections.synchronizedList())
- 查看堆栈中异常是否带
✅ 4. 检查是否误把 Iterator 当成 ListIndex 使用
有人试图用 iterator.next() 的返回次数当“当前下标”,然后去 list.get(i) ——这不仅冗余,还极易出错(尤其集合被修改后索引失效)。
-
反模式:
int idx = 0; for (Iterator<string> it = list.iterator(); it.hasNext(); idx++) { String s = it.next(); if ("target".equals(s)) { list.set(idx, "replaced"); // ❌ 危险!idx 可能已不同步 } }</string> -
更稳妥的方式(如需索引):
- 改用普通 for 循环(适用于 ArrayList 等支持随机访问的集合)
- 或用
ListIterator(支持nextIndex()/previousIndex()获取逻辑位置)
? 实用排查小技巧
- 在调试时,在
next()前加断点,观察it.hasNext()返回值; - 日志中打印
list.size()和it的状态(如it.getClass().getSimpleName()),确认是否为ArrayList$Itr等标准实现; - 使用 IDE 的「Evaluate Expression」实时执行
it.hasNext(),避免凭空猜测; - 若需边遍历边收集/过滤,优先考虑 Java 8+ 的
stream().filter(...).collect(...),语义清晰且不易出错。
不复杂但容易忽略:Iterator 的安全性,全系于 hasNext() 与 next() 的严格配对,以及对 remove() 的克制使用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











