文章目录
- 311. Java Stream API - 使用收集器作为终端操作
- ✅ **使用 Collector 收集流元素**
- **收集器的不同类型**
- **收集器的限制**
- 示例:使用收集器收集流中的元素
- 示例 1:收集到 `List` 中
- 输出:
- 示例 2:收集到 `Set` 中(去重)
- 输出:
- 示例 3:使用 `Supplier` 创建 `LinkedList` 并收集元素
- 输出:
- ✅ **不可变集合**
- 示例:收集到不可变集合
- 输出:
- ✅ **自定义收集器**
- 小结:
311. Java Stream API - 使用收集器作为终端操作
在Java中,Stream API提供了强大的方式来处理集合数据,其中collect()方法是一种常用的终端操作。该方法允许我们将流中的元素收集到不同类型的集合中,如List、Set或者自定义的集合类型。collect()方法的参数是一个Collector对象,它定义了如何将流中的元素累积到目标集合。
✅使用 Collector 收集流元素
collect()方法是 Stream 接口中的一个终端方法,接收一个Collector对象作为参数。Collector接口定义了一个API,用于收集数据并将其存储到内存结构中。你可以通过收集器将数据收集到任何实现了Collection接口的类中,或者收集到Map中,甚至是创建字符串或者其他类型的集合。
Java 提供了许多常用的收集器,这些收集器可以通过Collectors工厂类来创建。常见的收集器包括:
Collectors.toList():将流元素收集到List中。Collectors.toSet():将流元素收集到Set中。Collectors.toMap():将流元素收集到Map中。
如果这些内置的收集器不能满足需求,你还可以通过实现Collector接口来创建自定义收集器。
收集器的不同类型
- 收集到
Collection中:你可以使用Collectors.toList()或Collectors.toSet()将流中的元素收集到List或Set中。 - 自定义收集器:如果你需要收集元素到一个不同的集合类型,可以使用
toCollection(supplier)方法。通过这个方法,你可以指定使用特定的Supplier来创建集合。
收集器的限制
- 专门化流:
IntStream、LongStream和DoubleStream是数值流,它们只支持一个收集器,即不接受Collector类型的参数。因此,无法直接在这些流上使用Collectors.toList()或Collectors.toSet()。
示例:使用收集器收集流中的元素
示例 1:收集到List中
List<Integer>numbers=IntStream.range(0,10).boxed().collect(Collectors.toList());System.out.println("numbers = "+numbers);此代码段首先使用IntStream.range(0, 10)生成一个从 0 到 9 的整数流。boxed()方法将IntStream转换为Stream<Integer>,然后通过collect(Collectors.toList())将这些元素收集到一个List中。
输出:
numbers=[0,1,2,3,4,5,6,7,8,9]示例 2:收集到Set中(去重)
Set<Integer>evenNumbers=IntStream.range(0,10).map(number->number/2).boxed().collect(Collectors.toSet());System.out.println("evenNumbers = "+evenNumbers);此代码段先通过IntStream.range(0, 10)生成一个从 0 到 9 的整数流。然后,使用map()方法将每个数字除以 2,接着将流转换为Stream<Integer>。最后,通过collect(Collectors.toSet())将结果收集到Set中,自动去除重复值。
输出:
evenNumbers=[0,1,2,3,4]示例 3:使用Supplier创建LinkedList并收集元素
LinkedList<Integer>linkedList=IntStream.range(0,10).boxed().collect(Collectors.toCollection(LinkedList::new));System.out.println("linked list = "+linkedList);在这个示例中,使用toCollection()方法和LinkedList::new提供的Supplier来创建LinkedList实例,最终将Stream<Integer>中的元素收集到LinkedList中。
输出:
linked list=[0,1,2,3,4,5,6,7,8,9]✅不可变集合
有时候,你可能需要收集流中的元素到一个不可变的集合中。Collectors工厂类提供了toUnmodifiableList()和toUnmodifiableSet()两个方法,分别用于创建不可变的List和Set。
示例:收集到不可变集合
List<Integer>immutableList=IntStream.range(0,5).boxed().collect(Collectors.toUnmodifiableList());System.out.println("immutableList = "+immutableList);输出:
immutableList=[0,1,2,3,4]这个immutableList是不可变的,因此不能再向其中添加、删除或修改元素。
✅自定义收集器
如果你有特别的需求,无法满足于Collectors类提供的常用收集器,你可以实现自己的Collector接口。例如,假设你希望根据某些特定规则将流中的元素分组或累积到自定义的结构中。通过实现Collector接口,你可以完全控制元素的收集过程。
小结:
- 常用收集器:
Collectors.toList()、Collectors.toSet()、Collectors.toMap()等,适用于将流元素收集到常见的集合类型中。 - 自定义收集器:通过实现
Collector接口,你可以创建自己的收集器,收集元素到自定义的集合中。 - 不可变集合:
toUnmodifiableList()和toUnmodifiableSet()让你可以轻松地创建不可变集合。 - 专门化流:
IntStream、LongStream和DoubleStream不能使用接受Collector参数的collect()方法,只支持一个特殊的收集操作。
收集器是 Java Stream API 中非常强大的功能,通过掌握它的使用,你可以灵活地将流中的元素累积到各种集合中,并且能够根据需求进行扩展和定制。