for-each是Iterator的语法糖,二者底层均依赖Iterable接口,但Iterator支持安全删除、索引控制与遍历流程定制,for-each更简洁却禁止结构修改且缺乏灵活性;性能依集合类型而异:ArrayList宜用传统for,LinkedList宜用for-each或Iterator,HashSet等则优先for-each。

底层实现相同,但控制粒度不同
for-each 循环本质上是 Iterator 的语法糖,编译后会自动转换成调用 iterator().hasNext() 和 iterator().next() 的代码。两者都依赖集合实现的 Iterable 接口,适用范围一致:所有实现了 Iterable 的集合(List、Set、Queue 等)和数组。
能否在遍历时安全删除元素
这是最实用也最容易踩坑的区别:
- Iterator 支持安全删除:调用 iterator.remove() 可在遍历中途移除当前元素,不会抛异常,且逻辑清晰——只删刚取出来的那个
- for-each 完全禁止修改集合结构:哪怕只是写一行 list.remove(obj),运行时就会触发 ConcurrentModificationException。因为 for-each 隐藏了迭代器引用,无法调用其 remove 方法;而直接操作集合会破坏迭代器内部的 modCount 校验机制
是否需要访问索引或控制遍历流程
for-each 为简洁而牺牲灵活性:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 它不提供当前下标,想记录位置得额外声明 int i = 0 并手动递增,容易出错
- 无法倒序、跳步、暂停或复用迭代状态(比如嵌套遍历中想“回退一步”或共享同一迭代逻辑)
- Iterator 则完全可控:你可以反复调用 hasNext() 判断、用 next() 拿值、甚至配合 ListIterator 实现双向遍历
性能与集合类型强相关
选择哪种方式,还得看底层数据结构:
立即学习“Java免费学习笔记(深入)”;
- 对 ArrayList:传统 for 循环最快(O(1) 随机访问),for-each 和 Iterator 性能接近,略慢 5–10%
- 对 LinkedList:for-each 和 Iterator 明显更快(顺序访问 O(1));传统 for 循环每次 get(i) 都要从头遍历,变成 O(n²),应避免
- 对 HashSet、TreeSet 等无序/非索引集合:三者底层都走迭代器,性能差异可忽略,优先选 for-each 提高可读性

















