Iterator 遍历的核心优势是解耦+安全+统一:无需关心集合具体类型,支持遍历时安全删除元素,避免下标越界和 ConcurrentModificationException。

Iterator 遍历集合的核心优势不是“更短”,而是**解耦 + 安全 + 统一**——它让你不用关心集合是 ArrayList、HashSet 还是 LinkedList,也能在遍历时安全删元素,还不用担心下标越界或 ConcurrentModificationException。
为什么不能直接用 for 循环遍历所有集合?
因为不是所有集合都支持索引访问:HashSet、LinkedHashSet、TreeSet 没有 get(int index) 方法;HashMap 的 keySet() 返回的也是无序不可索引的 Set。强行写 for (int i = 0; i 会编译失败。
-
ArrayList可以用索引,但HashSet不行 ——Iterator是唯一能通吃所有Collection实现的遍历方式 - 增强
for循环(for (String s : list))底层就是Iterator,但它隐藏了remove()能力,删元素时必须显式用Iterator - 索引遍历还容易写出
i 这种越界 bug;hasNext()天然防越界
遍历时删除元素,为什么必须用 it.remove()?
直接调用 list.remove(obj) 或 set.remove(obj) 会触发 ConcurrentModificationException —— 因为集合内部的 modCount 和迭代器记录的 expectedModCount 对不上,fail-fast 机制立刻报错。
- 只有
Iterator.remove()会同步更新两个计数器,保证一致性 - 必须先调用一次
next(),才能调用remove();否则抛IllegalStateException - 不能连续两次
remove(),中间必须穿插next()
Iteratorit = list.iterator(); while (it.hasNext()) { String s = it.next(); if ("banana".equals(s)) { it.remove(); // ✅ 正确:安全删除 } } // ❌ 错误示例: // list.remove("banana"); // 报 ConcurrentModificationException // it.remove(); // 报 IllegalStateException(没调过 next)
Iterator 的 fail-fast 是保护还是限制?
它是保护,但只在单线程场景下有效 —— ArrayList、HashMap 等非线程安全集合的 Iterator 会在检测到外部修改时立即失败,避免返回脏数据或无限循环。
- 多线程环境下,
Iterator无法真正保证线程安全;需改用CopyOnWriteArrayList或加锁 -
ConcurrentHashMap的迭代器是弱一致性的,不抛ConcurrentModificationException,但可能看不到最新修改 - fail-fast 不是并发控制机制,只是调试友好型检查
什么时候该换用 ListIterator 或 Spliterator?
当你需要的功能超出 Iterator 能力边界时:
立即学习“Java免费学习笔记(深入)”;
- 要双向遍历(往前走、往后走)、或在遍历时添加元素 → 用
ListIterator(仅限List实现) - 处理大数据量且想利用多核并行遍历 → 用
Spliterator(配合Stream.parallelStream()) - 普通遍历 + 安全删除,
Iterator就是最简、最稳的选择
collection.iterator() 获取新实例 —— 这不是 bug,是设计使然。










