java流式编程 Collector接口


一、接口定义

public interface Collector<T, A, R> {

    Supplier<A> supplier();
    BiConsumer<A, T> accumulator();
    BinaryOperator<A> combiner();
    Function<A, R> finisher();
    Set<Characteristics> characteristics();
	......省略
   }

二、接口泛型<T, A, R>

T : 要处理的元素的类型

A : 累加器的类型

R : 返回结果的类型

三、接口方法

以 Collectors.toList() 为例

public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

(1)supplier方法:ArrayList::new,提供了一个ArrayList的累加器A;

A a1 = supplier.get();

(2)accumulator():List::add,将传去的元素T添加到累加器A中,
它接受两个参数,第一个是累加器list,第二个是遍历到的流中的第n个元素;

accumulator.accept(a1, t1);

(3)combiner():(left, right) -> { left.addAll(right); return left; } ,用于并行流执行时合并两个累加器list到一个累加器list中;

A a3 = combiner.apply(a1, a2)

(4)finisher():用于完成时,将累加器的结果A转换成想要的结果R,不需要转换时可以使用 t -> t;表达式表示;

R r1 = finisher.apply(a3);

(5)characteristics(),它会返回一个不可变的Characteristics集合,用于定义
了收集器的行为;

Set<Collector.Characteristics> characteristics = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH));

(6)创建累加器和结果类型一样的Collector

public static<T, R> Collector<T, R, R> of(Supplier<R> supplier,
                                              BiConsumer<R, T> accumulator,
                                              BinaryOperator<R> combiner,
                                              Characteristics... characteristics) {

(7)创建包含全部收集过程的Collector

public static<T, A, R> Collector<T, A, R> of(Supplier<A> supplier,
                                                 BiConsumer<A, T> accumulator,
                                                 BinaryOperator<A> combiner,
                                                 Function<A, R> finisher,
                                                 Characteristics... characteristics) {

(8) 枚举 Characteristics

Characteristics包含三种类型:

1、UNORDERED:归约结果不受流中项目的遍历和累积顺序的影响,即流归约结果是无序的,可以并行执行归约。

2、CONCURRENT:accumulator函数可以从多个线程同时调用,且该收集器可以并行归约流。如果收集器没有标为UNORDERED,那它仅在用于无序数据源时才可以并行归约。

3、IDENTITY_FINISH:这表明完成器方法返回的函数是一个恒等函数,可以跳过。这种情况下,累加器对象将会直接用作归约过程的最终结果。这也意味着,将累加器A不加检查地转换为结果R是安全的,即不需要定义finisher,或定义为 t -> t 。

四、接口实现类

CollectorImpl实现了Collector接口,里面仅仅定义了5个函数的实例,接收实例的构造方法以及各个函数的get方法。

 static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
        private final Supplier<A> supplier;
        private final BiConsumer<A, T> accumulator;
        private final BinaryOperator<A> combiner;
        private final Function<A, R> finisher;
        private final Set<Characteristics> characteristics;

        CollectorImpl(Supplier<A> supplier,
                      BiConsumer<A, T> accumulator,
                      BinaryOperator<A> combiner,
                      Function<A,R> finisher,
                      Set<Characteristics> characteristics) {
            this.supplier = supplier;
            this.accumulator = accumulator;
            this.combiner = combiner;
            this.finisher = finisher;
            this.characteristics = characteristics;
        }

        CollectorImpl(Supplier<A> supplier,
                      BiConsumer<A, T> accumulator,
                      BinaryOperator<A> combiner,
                      Set<Characteristics> characteristics) {
            this(supplier, accumulator, combiner, castingIdentity(), characteristics);
        }

        @Override
        public BiConsumer<A, T> accumulator() {
            return accumulator;
        }

        @Override
        public Supplier<A> supplier() {
            return supplier;
        }

        @Override
        public BinaryOperator<A> combiner() {
            return combiner;
        }

        @Override
        public Function<A, R> finisher() {
            return finisher;
        }

        @Override
        public Set<Characteristics> characteristics() {
            return characteristics;
        }
    }

总结

要想更好的理解流式编程,学习Collertor接口是必不可少的,不仅要学习jdk中已经实现了的Collertor,更要学会定义适合自己业务的Collertor。

猜你喜欢

转载自blog.csdn.net/qq_43985303/article/details/130967583