Java Stream API的引入极大地简化了集合(Collection)的处理方式,使得开发者能够以声明式的方式处理数据集合。其中,Collector接口是Stream API中一个非常重要的组成部分,它提供了一种灵活的方式来收集Stream处理的结果。
文章目录- Collector接口概述
- 核心方法
- Characteristics枚举
- Collector接口的实现
- 常用收集器示例
- Collector接口的执行原理
- 核心方法
- Characteristics枚举
- 常用收集器示例
Collector接口概述
Collector接口是Java 8中引入的一个泛型接口,它位于java.util.stream
包下。Collector接口主要用于将Stream中的元素收集到某种容器中,如List、Set、Map等。Collector接口定义了四个核心方法(以及一个枚举类型),这些方法共同协作完成收集任务。
核心方法
- Supplier supplier():返回一个空的结果容器(A类型),用于存放收集的结果。这个容器是累积器(accumulator)操作的目标。
- BiConsumer<A, T> accumulator():一个接受两个参数的函数,第一个参数是累积器(accumulator)的当前值(A类型),第二个参数是Stream中的当前元素(T类型)。该函数用于将Stream中的元素添加到累积器中。
- BinaryOperator combiner():一个函数,用于并行流中合并两个累积器的结果。当并行流中的不同部分被并行处理时,每个部分都会有一个累积器,最终这些累积器的结果需要被合并。
- Function<A, R> finisher():一个函数,用于将累积器的最终状态(A类型)转换为最终结果(R类型)。在串行流中,这一步是可选的,因为累积器的最终状态可能已经是所需的结果类型。
- Set characteristics():返回一个不可变的集合,包含Collector的特征值。这些特征值用于优化收集过程,如并发执行、无序性等。
Characteristics枚举
Collector接口中的Characteristics枚举定义了三个可能的特征值:
- CONCURRENT:表示此收集器支持并发执行。
- UNORDERED:表示收集结果不保证与Stream中元素的遍历顺序一致。
- IDENTITY_FINISH:表示finisher函数是一个恒等操作,即不需要进行额外的转换。
Collector接口的实现
Collector接口的实现通常通过Collectors工具类中的静态方法来完成。Collectors类提供了大量的静态方法,这些方法返回不同类型的Collector实例,以满足不同的收集需求。
常用收集器示例
toList():将Stream中的元素收集到一个List中。
代码语言:javascript复制List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> collectedNames = names.stream().collect(Collectors.toList());
toSet():将Stream中的元素收集到一个Set中,自动去重。
代码语言:javascript复制Set<String> uniqueNames = names.stream().collect(Collectors.toSet());
toMap():将Stream中的元素按照指定的键值对收集到一个Map中。
代码语言:javascript复制Map<Integer, String> ageMap = names.stream()
.collect(Collectors.toMap(name -> name.length(), name -> name));
groupingBy():根据某个属性对流中的元素进行分组。
代码语言:javascript复制List<Person> people = Arrays.asList(new Person("Alice", 30), new Person("Bob", 25));
Map<Integer, List<Person>> byAge = people.stream()
.collect(Collectors.groupingBy(Person::getAge));
Collector接口的执行原理
在Stream的收集过程中,Collector接口的方法按以下顺序执行:
- 初始化:通过supplier()方法创建一个空的累积器(结果容器)。
- 累积:对于Stream中的每个元素,通过accumulator()方法将其添加到累积器中。在并行流中,这个过程可能在多个线程中并行进行。
- 合并(仅并行流):通过combiner()方法合并不同线程中的累积器结果。
- 完成:通过finisher()方法(如果定义了)将累积器的最终状态转换为最终结果。