Java 8中有一个Collector接口,主要是为Stream中的元素转换成其他值提供的一个接口,在Collectors工具类中有很多Collector接口的实现方式。
Collector的定义为Collector<T, A, R>, 其中泛型参数T表示Stream中元素的类型, A表示定义一个初始容器的类型,R表示最终转换的类型。
Collector接口主要定义了如下几个方法:
supplier:这个方法主要是生成一个初始容器,用于存放转换的数据。它返回一个
Supplier<A>类型,用Lambda表示为() -> Aaccumulator: 这个方法是将初始容器与Stream中的每个元素进行计算,它返回一个
BiConsumer<A, T>类型,用Lambda表示为(A, T) -> voidcombiner: 这个方法用于在并发Stream中,将多个容器组合成一个容器,它返回一个
BinaryOperator<A>类型,用Lambda表示为(A, A) -> Afinisher:这个方法用于将初始容器转换成最终的值,它返回一个
Function<A, R>类型,用Lambda表示为A -> Rcharacteristics: 这个方法返回该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方法是一样的。