目标
完成一个简单的MyListCollector,能将对应的Stream转换为List
Collector是什么?
举个具体的例子:
list.stream().filter(x -> x > 2).collect(new MyListCollector());
我们想要将一个list中大于2的所有元素都筛选出来,首先list转化为stream,对每一个元素进行判断。但是判断完以后,我们如何将stream转换为我们想要的类型呢?这时候可以使用collect()方法,collect()方法需要的参数就是一个Collector,这个Collector告诉了collect方法,如何去将这个stream转换为我们想要的对象。
Collector接口
collect方法接收的Collector,都必须实现Collector接口,我们简单的看一下Collector接口:
- 先来看一下泛型
T:Collector需要操作的对象,也就是传进来的参数;A:中间容器,操作过程中存储T的容器;R:返回的结果。
- 看一下接口方法
public interface Collector<T, A, R> {
Supplier<A> supplier();
BiConsumer<A, T> accumulator();
BinaryOperator<A> combiner();
Function<A, R> finisher();
Set<Characteristics> characteristics();
}
Collector接口需要我们实现的一共五个,前4个定义了如何将传进来的数据进行处理,返回。最后一个方法定义了是否允许使用多线程处理,如何优化处理过程。
Supplier<A> supplier():提供一个容器,即接口泛型的A,所以返回类型Supplier<A>的泛型(返回类型)为A。所以我们的接口此方法实现为:
public Supplier<List<E>> supplier() {
return ArrayList::new;
}
BiConsumer<A, T> accumulator():这个方法定义了如何处理传入的参数。T为传入的参数,A为容器,也就是说,如何将传入的参数(A)放到容器(T)里。我们的接口,此方法实现为:
public BiConsumer<List<E>, E> accumulator {
return List::add;
}
Function<A, R> finisher():我们刚刚已经提到了,A只是作为一个中间容器,R才是最终的返回值。这个方法,就是用于定义如何将容器转换为最终结果的。所以我们的接口此方法的实现为:
public Function<List<E>, List<E>> finisher() {
return Function.identity();
}
BinaryOperator<A> combiner():此方法用于,当Stream被分割为多个的时候,如何将多个中间容器结合在一起。
public BinaryOperator<A> combiner() {
return (l1, l2) -> {
l1.addAll(l2);
return l1;
}
}
Set<Characteristics> characteristics():这个方法返回一个Set<Characteristics>,Characteristics是一个枚举类,一共有三个取值:
– UNORDERED:返回的结果是无序的;
– CONCURRENT:该Collector可以在多线程环境下使用,如果此Collector不是UNORDERED,那么这个Collector只有传入的数据是无序的时候,才能在多线程环境下使用;
– IDENTITY_FINISH:中间容器和返回值的类型一致。A转换为R的时候,不需要检查。
MyListCollector
结合以上,我们的接口实现为:
public class MyListCollector<E> implements Collector<E, List<E>, List<E>>{
@Override
public Supplier<List<E>> supplier() {
return ArrayList::new;
}
@Override
public BiConsumer<List<E>, E> accumulator() {
return List::add;
}
@Override
public BinaryOperator<List<E>> combiner() {
return (list1, list2) -> {
list1.addAll(list2);
return list1;
};
}
@Override
public Function<List<E>, List<E>> finisher() {
return Function.identity();
}
@Override
public Set<Characteristics> characteristics() {
return null;
}
}
参考:Java 8 in action

被折叠的 条评论
为什么被折叠?



