1. 概述

在 Java 中,有时候我们需要将一个 Iterator 转换为 List。虽然这看起来是个简单操作,但在不同场景下还是有一些“讲究”的。本文会介绍几种常见的转换方式,包括传统的 while 循环、Java 8 的新特性,以及使用一些常用第三方库(如 Guava 和 Apache Commons)的方法。

我们统一使用如下示例数据来演示:

Iterator<Integer> iterator = Arrays.asList(1, 2, 3).iterator();

2. 使用 while 循环

这是最经典、也是最直观的方式,在 Java 8 出现之前基本都是这么干的 ✅

List<Integer> actualList = new ArrayList<Integer>();
while (iterator.hasNext()) {
    actualList.add(iterator.next());
}

assertThat(actualList, containsInAnyOrder(1, 2, 3));

这种方式简单粗暴,兼容性好,适用于所有 JDK 版本 ❌ 不过代码略显啰嗦。

3. 使用 Java 8 的 forEachRemaining

Java 8 给 Iterator 加了个新方法:forEachRemaining(),我们可以配合方法引用让代码更简洁一点:

List<Integer> actualList = new ArrayList<Integer>();
iterator.forEachRemaining(actualList::add);

assertThat(actualList, containsInAnyOrder(1, 2, 3));

相比 while 循环,代码量少了不少,而且语义清晰 ✔️ 但仍然需要手动创建目标 List。

4. 使用 Java 8 的 Stream API

这个方法稍微绕一点:由于 Stream 是基于 Iterable 构建的,所以我们需要先把 Iterator 包装成 Iterable

Iterable<Integer> iterable = () -> iterator;

然后就可以愉快地使用 Stream 流式操作了:

List<Integer> actualList = StreamSupport
  .stream(iterable.spliterator(), false)
  .collect(Collectors.toList());

assertThat(actualList, containsInAnyOrder(1, 2, 3));

⚠️ 注意这里不能直接从 Iterator 创建 Stream,必须借助 StreamSupport.stream() 方法。

5. 使用 Google Guava

Guava 提供了两种方式,分别生成可变和不可变的 List:

5.1 创建不可变 List

List<Integer> actualList = ImmutableList.copyOf(iterator);

assertThat(actualList, containsInAnyOrder(1, 2, 3));

5.2 创建可变 List

List<Integer> actualList = Lists.newArrayList(iterator);

assertThat(actualList, containsInAnyOrder(1, 2, 3));

✔️ Guava 的 API 设计非常友好,代码简洁且意图明确。如果你项目中已经引入了 Guava,推荐优先使用它。

6. 使用 Apache Commons

Apache Commons Collections 也提供了工具类来完成这个任务:

List<Integer> actualList = IteratorUtils.toList(iterator);

assertThat(actualList, containsInAnyOrder(1, 2, 3));

✔️ 如果你已经在用 Apache Commons,这个方法也挺方便的。

7. 总结

总结一下,将 Iterator 转换为 List 有多种方式:

方式 是否推荐 说明
while 循环 ⚠️ 可用 最通用,适合老项目
forEachRemaining ✅ 推荐 Java 8+,简洁
Stream API ✅ 推荐 功能强大,适合链式处理
Guava ✅ 强烈推荐 简洁 + 类型安全
Apache Commons ✅ 推荐 工具齐全

最终选择哪种方式,可以根据项目依赖、团队习惯和性能需求灵活决定。所有示例代码都可以在 GitHub 上找到。


原始标题:Converting Iterator to List | Baeldung