forEachRemaining是Java 8为Iterator新增的默认方法,用于一次性消费迭代器中剩余所有元素,适合已手动调用部分next()后统一处理余下元素,复用迭代器状态,调用后迭代器耗尽。

forEachRemaining 是 Java 8 为 Iterator 接口新增的默认方法,用于**一次性消费迭代器中剩余的所有元素**,比传统 while 循环更简洁,且底层做了优化(比如对 ArrayList、HashSet 等集合的迭代器,可能直接遍历底层数组或哈希表,跳过逐个 hasNext()/next() 调用的开销)。
什么时候适合用 forEachRemaining?
当你已经手动调用过几次 next(),想把剩下的元素统一处理时;或者你拿到的是一个“半消耗”的迭代器(比如从某个中间状态开始),又不想重写循环逻辑。
- 避免重复写 while + hasNext + next 模板代码
- 在流式处理中配合
Spliterator或自定义迭代逻辑使用 - 某些场景下性能略优于手动循环(尤其对支持快速遍历的集合)
基本用法示例
假设有一个 List<String>,先取前两个元素,再用 forEachRemaining 处理剩下的:
List<String> list = Arrays.asList("a", "b", "c", "d", "e");
Iterator<String> it = list.iterator();
// 手动消费前两个
if (it.hasNext()) System.out.println("first: " + it.next()); // a
if (it.hasNext()) System.out.println("second: " + it.next()); // b
// 剩下的 c, d, e 用 forEachRemaining 一次性处理
it.forEachRemaining(s -> System.out.println("rest: " + s));
输出:
first: a
second: b
rest: c
rest: d
rest: e
和 for-each / Stream 的区别
-
for-each(增强 for 循环)本质是隐式获取新迭代器,不能“接着上次的位置”继续 -
Stream.forEach是对整个集合的一次性操作,不支持“跳过前 N 个再消费”这种分段逻辑 -
forEachRemaining是唯一能**复用已有迭代器状态**并批量消费剩余元素的标准方式
注意事项
- 调用后,迭代器处于“耗尽”状态:
hasNext()返回false - 如果迭代器不支持该操作(极少数自定义实现未覆盖默认方法),会抛
UnsupportedOperationException - 不保证线程安全;多线程并发修改集合+消费,仍需外部同步
- 无法中断或跳出 —— 它是“全量执行”,不像 for 循环可 break;如需条件终止,还是用传统 while


















