iterator 与 while 循环是 java 遍历的标准配合方式,提供安全删除、条件跳过等控制能力;for-each 本质基于 iterator,但无法满足精细操作需求;遍历 map 必须通过 keyset、values 或 entryset 视图获取 iterator。

Java 中的循环处理与 Iterator 并不是互斥关系,而是互补协作:Iterator 提供底层遍历能力,while 循环是其最自然、最可控的配合方式。for-each 语法虽简洁,但本质仍是基于 Iterator 实现;真正需要手动配合 Iterator 的场景,集中在安全删除、条件跳过或提前终止等操作中。
Iterator 的核心行为要理解清楚
迭代器不是“指针”,而是一个有状态的对象,初始时总在第一个元素之前。每次调用 next() 才会移动并返回当前元素;hasNext() 只负责探路,不改变位置。这两个方法必须成对使用——未检查 hasNext() 就调用 next(),会抛出 NoSuchElementException。
- 调用一次 next(),游标前进一位,且只能获取该位置元素一次
- remove() 方法只能删除上一次 next() 返回的那个元素,且每个 next() 后最多调用一次 remove()
- 迭代器一旦遍历完毕,不会自动复位;如需重头遍历,必须重新调用集合的 iterator() 获取新实例
用 while 循环配合 Iterator 是标准写法
这是最直观、最不易出错的遍历模式,适用于所有 Collection 类型(List、Set)以及 Map 的键、值、条目视图。
- 遍历 ArrayList 或 LinkedList:Iterator
it = list.iterator(); while (it.hasNext()) { String s = it.next(); /* 处理 s */ } - 遍历 HashSet 或 TreeSet:Iterator
it = set.iterator(); while (it.hasNext()) { Integer n = it.next(); /* 处理 n */ } - 遍历 HashMap 的键值对:Iterator
> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry e = it.next(); System.out.println(e.getKey() + "=" + e.getValue()); }
遍历时安全删除元素必须用 iterator.remove()
在循环中直接调用集合自身的 remove()(比如 list.remove(obj) 或 set.remove(obj)),会触发 ConcurrentModificationException。这是因为迭代器内部维护了修改计数器,集合结构变动后计数不一致就会报错。
- 正确做法:在调用 next() 获取元素后,立即用同一迭代器的 remove() 删除它
- 示例:过滤掉所有长度小于 3 的字符串
Iteratorit = list.iterator();
while (it.hasNext()) {
String s = it.next();
if (s.length() } - 注意:不能在一次 next() 后连续调用多次 remove(),也不能在尚未调用 next() 时调用 remove()
Map 遍历不能直接用 iterator(),要选对视图
Map 本身不实现 Collection 接口,所以没有直接的 iterator() 方法。必须先转为 keySet()、values() 或 entrySet() 三种视图之一,再调用它们的 iterator()。
- 只关心键:用 map.keySet().iterator()
- 只关心值:用 map.values().iterator()
- 需要键和值一起处理:务必用 map.entrySet().iterator(),避免反复 get(key) 带来的性能开销和潜在空指针风险
- 不要尝试用 for-each 遍历原始 map —— 编译不通过
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











