Collection 通过继承 Iterable 获得遍历能力,Iterable 提供 iterator() 等遍历入口,Collection 定义增删查等容器行为;Map 非 Collection 子接口故不可直接 for-each,但其 keySet() 等返回 Collection 可遍历。

Collection 接口本身不直接定义“怎么遍历”,而是通过继承 Iterable 接口,获得“能被遍历”的能力。这种设计不是冗余,而是职责分离:Iterable 负责“提供遍历入口”,Collection 负责“管理元素行为”。
Iterable 是遍历能力的契约
Iterable 接口只做一件事:声明“我能被 for-each 遍历”。它规定必须实现 iterator() 方法,返回一个 Iterator 对象。JDK 8 后还增加了 forEach(Consumer) 和 spliterator() 这两个默认方法,但核心仍是 iterator() —— 所有 for-each 循环底层都调用它。
- for (String s : list) 实际等价于 Iterator
it = list.iterator(); while (it.hasNext()) { String s = it.next(); ... } - 哪怕你写的是自定义类(比如 MyList),只要实现 Iterable,就能用 for-each,无需关心 Collection
Collection 是元素容器的契约
Collection 接口关注的是“集合该支持哪些操作”:增(add)、删(remove)、查(contains)、大小(size)、清空(clear)等。它不关心内部怎么存,也不规定遍历细节,只约定“我是一个元素集合”,并强制继承 Iterable —— 换句话说,“只要是 Collection,就必须能遍历”。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- List、Set、Queue 都是 Collection 的子接口,因此天然具备遍历能力
- Map 不是 Collection 的子接口,所以不能直接 for-each;但它的 keySet()、values()、entrySet() 返回的都是 Collection,就能遍历
为什么不让 Collection 自己定义 iterator()?
因为遍历是一种通用能力,不只属于集合。数组、字符串、甚至自定义的树或图结构,只要想支持 for-each,都可以实现 Iterable。把 iterator() 提到顶层接口,就避免了在 Collection、Map、CharSequence 等多个地方重复定义,也方便统一扩展(比如 forEach 默认实现可复用)。
- Iterable 是“能力接口”,强调“我能做什么”
- Collection 是“角色接口”,强调“我是什么”(一组元素的容器)
- 两者组合,既保持语义清晰,又支持灵活复用
实际编码中要注意的细节
虽然 Collection 继承 Iterable,但 Iterator 的 remove() 方法默认抛 UnsupportedOperationException。是否支持边遍历边删除,取决于具体实现类(如 ArrayList 支持,而 Collections.unmodifiableList 不支持)。
- 使用 it.remove() 前,务必确认当前迭代器支持该操作
- forEach() 和 forEachRemaining() 是安全的遍历方式,不会改变集合结构
- 不要在 for-each 循环里调用集合自身的 remove(),会触发 ConcurrentModificationException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










