iterator()方法返回的是实现了Iterator接口的实例,具备hasNext()、next()、remove()三个核心能力,具有一性、快照性与实现依赖性。

iterator() 方法返回的是什么类型对象
调用 iterator() 得到的是一个实现了 Iterator 接口的实例,不是数组、不是 List,更不是原始集合本身。它只提供三个核心能力:hasNext()、next()、remove()(后者可选,部分实现抛 UnsupportedOperationException)。这个对象是“一次性的”——遍历完或中途抛异常后,不能重置,必须重新调用 iterator() 获取新实例。
用 while + hasNext() + next() 遍历最稳妥
这是最通用、最可控的方式,适用于所有实现了 Iterable 的集合(ArrayList、HashSet、LinkedList、自定义类等),且能安全处理空集合和并发修改检测(fail-fast)。
常见错误包括:在循环体里多次调用 next() 导致跳过元素;或把 hasNext() 放在 while 外做一次判断就直接 next(),引发 NoSuchElementException。
正确写法示例:
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String item = it.next(); // 每次只调用一次
System.out.println(item);
}
增强 for 循环底层就是 iterator(),但有隐藏限制
写 for (String s : list) 时,编译器会自动展开为等价的 iterator() 调用。好处是简洁;坏处是无法在遍历时调用 remove(),否则抛 ConcurrentModificationException;也无法获取当前迭代位置索引;更无法在循环中区分“刚取到的元素”和“下个待取元素”。
如果你需要边遍历边删除,必须显式用 Iterator 并调用其 remove() 方法:
Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
if (it.next() % 2 == 0) {
it.remove(); // 安全删除
}
}
注意不同集合的 iterator() 行为差异
ArrayList.iterator() 返回的是内部静态类 Itr,支持快速失败(fast-fail),但不保证线程安全;CopyOnWriteArrayList.iterator() 返回的是快照,遍历时即使原集合被修改也不抛异常,但看不到新增元素;ConcurrentHashMap.keySet().iterator() 是弱一致性迭代器,可能漏掉某些刚插入的条目,也不会抛 ConcurrentModificationException。
所以不能假设所有 iterator() 行为一致——是否可见最新修改、是否线程安全、是否支持删除,都取决于具体集合实现。
真正容易被忽略的,是迭代器与集合状态的绑定时机:它不是“活视图”,而是“创建时刻的快照或代理”,这个边界一旦混淆,就会在多线程或动态修改场景下出现难以复现的逻辑偏差。

















