← 返回题目列表

Java 中 Iterable 和 Iterator 有什么区别?

高频 中等 第 11 / 25 题 更新于 2026/07/28
IterableIteratorJava集合

简化版

Iterable 表示一个对象可以被遍历,核心方法是 iterator()Iterator 表示一次具体的遍历过程,核心方法是 hasNext()next()。集合通常实现 Iterable,每次调用 iterator() 返回一个新的 Iterator

详细版

IterableIterator 的职责不同:

  • Iterable 是可迭代对象,例如集合本身。
  • Iterator 是迭代器对象,保存当前遍历状态。

增强 for 循环要求目标对象实现 Iterable,编译后大致会转成调用 iterator() 获取迭代器,再循环调用 hasNext()next()

一个集合可以创建多个迭代器,每个迭代器有自己的游标,所以多个遍历过程可以相互独立。

完整版教学

一、Iterable 表示可被遍历

Iterable<T> 的核心方法是:

Iterator<T> iterator();

它的含义是:这个对象能够提供一个迭代器。

集合类如 ListSet 通常都实现了 Iterable,所以可以写:

for (String item : list) {
    System.out.println(item);
}

二、Iterator 表示一次遍历

Iterator<T> 的常用方法是:

boolean hasNext();
T next();
default void remove();

它保存当前遍历位置。调用 next() 后,游标会向后移动。

同一个集合可以生成多个迭代器:

Iterator<String> it1 = list.iterator();
Iterator<String> it2 = list.iterator();

it1it2 的游标互不影响。

三、增强 for 和它们的关系

增强 for 本质上依赖 Iterable

代码:

for (String s : list) {
    System.out.println(s);
}

可以理解成:

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    System.out.println(s);
}

所以,如果自定义类想支持增强 for,通常实现 Iterable 即可。

四、为什么不让集合自己实现 Iterator

如果集合对象自己就是迭代器,它内部就必须保存游标。这样同一个集合同时被两段代码遍历时,游标会互相干扰。

例如外层循环和内层循环同时使用同一个集合,如果只有一个游标,遍历结果会混乱。

因此更好的设计是:集合实现 Iterable,每次返回新的 Iterator。遍历状态放在迭代器里,而不是放在集合本身。

五、Iterator 和 ListIterator 的区别

ListIteratorIterator 的增强版,只适用于列表。

它支持:

  • 双向遍历。
  • 获取前一个元素。
  • 遍历过程中修改元素。
  • 在当前位置插入元素。

普通 Iterator 更通用,但能力更少。面试中如果问双向遍历,可以顺带提到 ListIterator

六、常见误区

常见误区是把 IterableIterator 当成同一个东西。

更准确的理解是:

  • Iterable 是工厂入口,负责产生迭代器。
  • Iterator 是一次遍历过程,负责移动游标。

一个对象可迭代,不代表它自己就是迭代器。

七、常见误区与追问

Iterable 表示“能创建迭代器”,Iterator 表示“一次遍历的游标状态”。同一个集合连续调用2次 iterator() 应得到两个独立游标,它们各自从起点开始;若集合自身同时充当 Iterator,嵌套循环就会互相覆盖位置。增强 for 依赖的是 Iterable 契约。

检查维度判定依据
Iterable提供 iterator(),可重复创建游标
Iterator保存当前位置,提供 hasNext/next
Iterable -> Iterator#1(cursor=0), Iterator#2(cursor=0)

记忆钩子:Iterable 是“可走的路”,Iterator 是“正在走的人”。

  • 误区:Iterable 自己保存遍历位置。 游标应属于每个 Iterator,否则多次遍历会冲突。
  • 追问:Iterator 能重复使用吗? 到达末尾后通常不可重置,需要重新从 Iterable 获取。
  • 误区:实现 Iterator 就能用于增强 for。 增强 for 需要数组或 Iterable,单独 Iterator 不满足语法要求。
  • 追问:为什么 iterator() 每次返回新对象? 保证并行或嵌套遍历拥有独立状态。
  • 追问:Spliterator 与它们有什么关系? Spliterator 额外支持拆分和特征描述,便于 Stream 并行处理。

八、加强记忆

Iterable 是“能不能被遍历”,Iterator 是“正在怎么遍历”。集合实现 Iterable,遍历过程交给 Iterator,这就是 Java 集合和迭代器模式的核心关系。