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 上找到。