Iterator 是 Java 中定义遍历集合契约的接口,提供 hasNext()、next()、remove() 三个方法;必须先调用 hasNext() 判断再调用 next(),否则越界时抛 NoSuchElementException。

Iterator 是什么:不是工具类,而是遍历协议
Iterator 是 java.util.Iterator 接口,不是某个具体类,它定义了一套“怎么安全走完一个集合”的契约。你拿到的 it(比如 list.iterator() 返回的对象)是某个集合自己实现的迭代器实例,但对外只暴露这三个方法:hasNext()、next()、remove()。它不关心底层是数组、链表还是哈希桶——你也不该关心。
为什么必须用 hasNext() + next() 组合,不能跳过判断直接 next()
因为 next() 不做兜底检查,它假设你已经确认“还有下一个”。跳过 hasNext() 直接调用 next(),一旦指针已到末尾,立刻抛出 NoSuchElementException。这不是 bug,是设计使然:Iterator 把“是否继续”的决策权交还给你,避免隐式异常掩盖逻辑错误。
- ✅ 正确写法:
while (it.hasNext()) { String s = it.next(); /* 安全 */ } - ❌ 危险写法:
for (int i = 0; i < list.size(); i++) { String s = list.get(i); /* 仅 ArrayList 可用,且删元素会崩 */ } - ⚠️ 常见误用:在
while循环里漏掉hasNext()判断,或把next()写在循环条件里(如while ((s = it.next()) != null)),这会导致多取一次、越界或 NPE。
remove() 的坑:不是“删当前”,而是“删上一个 next() 拿到的”
remove() 删除的不是“光标下面那个元素”,而是**刚刚由 next() 返回的那个元素**。这意味着它严重依赖调用顺序:
- 没调过
next()就调remove()→IllegalStateException - 连续调两次
remove()(中间没穿插next())→ 同样抛IllegalStateException - 它只能删一次,删完之后必须再
next()一次才能再删下一个
所以安全删除的唯一模式就是:if (满足条件) { it.remove(); },且这个 if 必须出现在 next() 之后、下一轮循环之前。
立即学习“Java免费学习笔记(深入)”;
Fail-fast 是保护机制,不是故障信号
当你用 it 遍历时,若其他代码(哪怕是同一个线程)调了 list.add() 或 list.remove(),it.hasNext() 或 next() 下次调用就会立即抛 ConcurrentModificationException。这不是并发问题,是 Java 在告诉你:“集合结构变了,我没法保证接下来遍历结果可靠”。
- ✅ 正解:遍历时删元素,只用
it.remove() - ✅ 多线程场景:换
CopyOnWriteArrayList或ConcurrentHashMap等线程安全集合 - ❌ 错误应对:用 try-catch 包住迭代逻辑来“吞掉”这个异常——它本意是帮你定位逻辑错误,不是让你绕过去
最常被忽略的一点:增强 for 循环(for (String s : list))底层就是 Iterator,所以它同样受 fail-fast 约束,且不支持删除操作——想删,就必须显式写 Iterator。










