自定义收集器,实现集合元素求和
java.util.stream.Stream#collect(java.util.stream.Collector<? super T,A,R>) [T为元素类型,A为容器类型,R为最终返回类型] ;此方法接受一个Collector类型的收集器;所以自定义就需要实现Collector接口。先不论如何用收集器实现,可以试想一下按照常理来说求和一个集合,首先需要声明一个变量用于存放累加的值,在循环迭代中进行累加元素。所以Collector接口操作集合也类似,方法列表如下:
supplier:返回一个存放迭代元素的容器
accumulator:累加元素
combiner:合并多个容器的值
finisher:返回最终的结果
characteristics:为收集器设置特性->>多个线程同时可以调用累加器进行累加,是否保证有序,是否调用收集最终的结果,也就是调用finisher方法
实现求和代码如下:
/**
* 自定义收集器--->>>>集合中元素SUM统计
*
* @author haibin.tang
* @create 2018-01-29 下午5:30
**/
public class TotalCollectors {
static class TotalCollectorImpl implements Collector<Integer, TotalContainer, Integer> {
/**
* 返回每次迭代存放数据的容器
*
* @return
*/
@Override
public Supplier<TotalContainer> supplier() {
return TotalContainer::new;
}
/**
* 累加器,由容器实现决定当前元素要怎么处理,这里是相加
*
* @return
*/
@Override
public BiConsumer<TotalContainer, Integer> accumulator() {
return TotalContainer::add;
}
/**
* 合并两个容器的元素,只有并行并且{@linkplain com.wz.java8.TotalCollectors.TotalCollectorImpl#characteristics()}中没有设置Characteristics.CONCURRENT才会调用
*
* @return
*/
@Override
public BinaryOperator<TotalContainer> combiner() {
return null;
}
/**
* 返回最终的结果
*
* @return
*/
@Override
public Function<TotalContainer, Integer> finisher() {
return TotalContainer::total;
}
/**设置收集器特性
* Characteristics.CONCURRENT 多个线程可以同时调用累加器
* Characteristics.UNORDERED 返回结果集与输入顺序有可能不一致
* Characteristics.IDENTITY_FINISH 标识 finisher() 方法实现可以省略,不会调用该方法,并且返回的是容器对象
* @return 收集器特性集合
*/
@Override
public Set<Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH));
}
}
/**
* 容器用来累加每次迭代的值
*/
static class TotalContainer {
private int total;
public TotalContainer add(int number) {
total += number;
return this;
}
private int total() {
return total;
}
}
public static void main(String[] args) {
System.out.println((Stream.of(1, 2, 3, 4, 5, 6).collect(new TotalCollectorImpl())));
}
}
关于并行操作流还没学习到,后续补充