文章目录
- 301. Java Stream API - 元素收集方式详解(进阶版)
- 🎯 为什么要关注收集方式?
- 🧰 收集到自定义集合(Homemade Collection)
- 🧩 收集到 Set(去重)
- 🔒 收集到不可变 Set
- 📦 收集到数组(Array)
- 🌱 toArray()(基础版本)
- 🌳 toArray(IntFunction<A[]> generator)
- 💡 总结:不同收集方式对比
301. Java Stream API - 元素收集方式详解(进阶版)
在使用 Stream API 处理数据时,最终我们往往需要将处理结果“收集”到某种容器中。这个容器可以是 List、Set、自定义集合,甚至是一个数组。
🎯 为什么要关注收集方式?
选择不同的收集方式不仅会影响性能(如是否复制数组、是否预设容量等),还会影响返回结果的类型(是否可修改、是否线程安全等)。本节我们详细讲解各种收集方式的适用场景与实现方式。
🧰 收集到自定义集合(Homemade Collection)
当你需要将结果收集到特定类型的集合中,比如你自定义的列表类或是三方库的集合类型(比如 Apache Commons、Guava 的集合),可以使用:
.collect(Collectors.toCollection(Supplier))这允许你灵活地定义要收集到哪种集合中。比如:
Stream<String>strings=Stream.of("one","two","three","four");List<String>result=strings.filter(s->s.length()==3).map(String::toUpperCase).collect(Collectors.toCollection(LinkedList::new));// 🔧 使用 LinkedListSystem.out.println("Class of result = "+result.getClass());System.out.println("result = "+result);📌 输出:
Classof result=classjava.util.LinkedListresult=[ONE,TWO]✅说明:可以用这个方式指定任何Collection子类,包括第三方集合或者自定义集合。
🧩 收集到 Set(去重)
如果你希望收集的元素去重,可以使用Collectors.toSet():
Stream<String>strings=Stream.of("one","two","three","four");Set<String>result=strings.filter(s->s.length()==3).map(String::toUpperCase).collect(Collectors.toSet());System.out.println("Class of result = "+result.getClass());System.out.println("result = "+result);📌 输出:
Classof result=classjava.util.HashSetresult=[ONE,TWO]✅说明:
- 默认返回的是
HashSet - 元素自动去重
- 元素顺序不可预测(因为是 HashSet)
🔒 收集到不可变 Set
如果你希望结果是不可变集合(防止被修改),可以使用:
.collect(Collectors.toUnmodifiableSet());示例:
Stream<String>strings=Stream.of("one","two","three","four");Set<String>result=strings.filter(s->s.length()==3).map(String::toUpperCase).collect(Collectors.toUnmodifiableSet());System.out.println("Class of result = "+result.getClass());System.out.println("result = "+result);📌 输出:
Classof result=classjava.util.ImmutableCollections$Set12result=[ONE,TWO]✅说明:尝试修改这个集合会抛出UnsupportedOperationException异常,适合用于不可变数据流转。
📦 收集到数组(Array)
🌱 toArray()(基础版本)
最基础的toArray()方法会返回Object[]:
Object[]arr=stream.toArray();缺点:丢失具体类型信息,需要强制类型转换。
🌳 toArray(IntFunction<A[]> generator)
推荐使用的版本,可以指定返回类型:
Stream<String>strings=Stream.of("one","two","three","four");String[]result=strings.filter(s->s.length()==3).map(String::toUpperCase).toArray(String[]::new);// 👈 使用构造方法引用System.out.println("result = "+Arrays.toString(result));📌 输出:
result=[ONE,TWO]✅说明:
String[]::new是构造数组的函数- 更安全,更推荐
💡 总结:不同收集方式对比
| 收集方式 | 适用场景 | 是否可变 | 是否可指定容器类型 | 特点 |
|---|---|---|---|---|
Collectors.toList() | 普通场景 | ✅ | ❌(返回ArrayList) | 最常用 |
Collectors.toUnmodifiableList() | 安全性优先 | ❌ | ❌ | Java 9+ |
Stream.toList() | 更高性能不可变 List | ❌ | ❌ | Java 16+ |
Collectors.toCollection(...) | 需要指定集合类型 | ✅ | ✅ | 高度灵活 |
Collectors.toSet() | 结果需去重 | ✅ | ❌(返回HashSet) | 自动去重 |
Collectors.toUnmodifiableSet() | 去重且不可变 | ❌ | ❌ | Java 9+ |
toArray() | 返回数组 | ✅ | ✅(重载版) | 常用于需要原始数组场景 |