Java 8中有一个Collector
接口,主要是为Stream中的元素转换成其他值提供的一个接口,在Collectors
工具类中有很多Collector
接口的实现方式。
Collector的定义为Collector<T, A, R>
, 其中泛型参数T
表示Stream中元素的类型, A
表示定义一个初始容器的类型,R
表示最终转换的类型。
Collector接口主要定义了如下几个方法:
supplier:这个方法主要是生成一个初始容器,用于存放转换的数据。它返回一个
Supplier<A>
类型,用Lambda表示为() -> A
accumulator: 这个方法是将初始容器与Stream中的每个元素进行计算,它返回一个
BiConsumer<A, T>
类型,用Lambda表示为(A, T) -> void
combiner: 这个方法用于在并发Stream中,将多个容器组合成一个容器,它返回一个
BinaryOperator<A>
类型,用Lambda表示为(A, A) -> A
finisher:这个方法用于将初始容器转换成最终的值,它返回一个
Function<A, R>
类型,用Lambda表示为A -> R
characteristics: 这个方法返回该Collector具有的哪些特征,返回的是一个
Set
, 分别是CONCURRENT
(并发),UNORDERED
(未排序),IDENTITY_FINISH
(finisher
方法直接返回初始容器)等特征的组合。
在Collectors
中有一个joining
方法,它是将Stream
中的字符序列类型的元素串接在一起,下面是一个例子:
1 | // 输出 abcd |
下面通过自己实现joining方法来理解如何实现Collector
接口。
定义自己实现的JoinCollector
类:
1 | public class JoinCollector implements Collector<CharSequence, StringBuilder, String> { |
其中,supplier
方法返回一个StringBuilder
对象,用于表示初始容器。
accumulator
方法返回的是StringBuilder
的append
方法的方法引用, 用于将Stream
中的元素加入到初始容器StringBuilder
中。
combiner
方法用于将多个StringBuilder
容器通过append
方法组合成一个StringBuilder
对象。
finisher
方法是将StringBuilder
对象通过toString
方法最终转换成String
对象。
使用自定义的Collector
的例子如下:
1 | // 输出 abcd |
得到的结果与Collectors.joining
方法是一样的。