iterable 是“能被遍历”的声明,iterator 是“怎么去遍历”的工具;iterable 提供 iterator() 方法返回 iterator 实例,二者分工协作实现遍历标准化。

Java 中 Iterator 和 Iterable 的关系,核心就一句话:Iterable 是“能被遍历”的声明,Iterator 是“怎么去遍历”的工具。二者不是同类概念,而是分工明确的协作关系。
Iterable 是能力契约,不是具体操作者
它只干一件事:告诉外界“我支持遍历”,并提供一个标准入口——iterator() 方法。只要类实现了 Iterable,就能用 for-each 循环,JVM 会自动调用它的 iterator() 获取真正的迭代器。ArrayList、HashSet、LinkedList 等所有常用集合都实现了它,连自定义容器也可以实现,只需返回一个合法的 Iterator 实例即可。
- 必须重写
iterator(),返回一个可用的 Iterator 对象 -
forEach()和spliterator()是 Java 8 后加的默认方法,不强制实现 - 它在
java.lang包里,说明它是语言级基础能力,不局限于集合框架
Iterator 是遍历执行者,封装状态和逻辑
它是一个独立的对象,持有当前遍历位置(游标)、判断是否还有元素(hasNext())、取出下一个元素(next()),甚至可选地删除刚取过的元素(remove())。每次调用 iterator() 都会新建一个 Iterator 实例,彼此状态互不影响。
-
hasNext()和next()必须配合使用:先判断,再获取,否则可能抛NoSuchElementException -
remove()是可选操作,多数场景不用;调用前必须已成功调用过next() -
forEachRemaining()是批量处理捷径,内部仍基于hasNext()/next()实现
为什么不能只用 Iterator?
因为 Iterator 本身不解决“从哪来”的问题。你不能凭空 new 一个 Iterator 去遍历 ArrayList —— 它没有构造参数接收集合引用。Iterable 就是桥梁:ArrayList 实现了 Iterable,所以你能写 list.iterator();而这个调用返回的,才是真正的 Iterator 实例(比如 ArrayList$Itr)。
- 没有 Iterable,每个集合就得自己定义一个类似
getIterator()的方法,接口不统一 - 没有 Iterator,
for-each就无法通用,编译器无从知道怎么遍历不同结构的容器 - 二者合起来,才构成“容器解耦 + 遍历标准化”的完整方案
常见误区提醒
别把 Iterable 当成 Iterator 的父接口——它们没继承关系;也别以为实现了 Iterator 就能直接用 for-each,只有实现 Iterable 才行。另外,增强 for 循环本质就是语法糖,编译后仍转为 Iterator 调用,所以底层仍是 fail-fast 机制,遍历时修改集合仍会抛 ConcurrentModificationException。
- Iterator 是工具对象,Iterable 是能力接口
- 一个类可以实现 Iterable,但通常不直接实现 Iterator(而是由内部类或辅助类实现)
- 自定义类想支持
for-each,只用实现 Iterable 并返回合理 Iterator 即可
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











