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。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_lrs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值