java8学习总结——Collector接口

概述

在JDK中对Collector的定义是一个可变的归约操作(A mutable reduction operation</a>)。是一种操作思想,分为计算元素、归集计算结果两个主要的步骤;为了保存计算元素的中间状态,所以会提供一个容器来完成中间状态和中间结果的保存。如下面的集合操作:

public class CollecorTest {

    public static void main(String[] args) {
            /**
             * 对所有元素追击后缀“suffix”
             * 再以map的形式输出,key和value都是元素本身
             */
            List<String> list = Arrays.asList("hello","world","welcome","yes","no");
            List<String> container = new ArrayList<>();  //创建一个中间容器,用来保存中间状态
            for (String element : list) {
                container.add(element+"suffix");  //对中间元素进行操作,并存入容器中
            }

            Map<String,String> map = new HashMap<String,String>();
            for (String element : container) {
                map.put(element,element); //再次操作改变集合的形式,归集结果          
            }
    }
}

在Collector接口提供四个方法:

      
       /**
         *  1、	Supplier<A> supplier();--> 不接受参数,返回一个值。充当提供容器的角色
         *  2、	BiConsumer<A, T> accumulator();--> 接收两个参数,不返回结果。其接收的两个参数,第一个是supplier提供的集合;第二个参数是待操作的元素,将元素操作完之后,放入集合中。
         *  3、	BinaryOperator<A> combiner(); --> 这个方法主要是应对并发操作时,会出现多个中间容器,需要通过conbiner方法将多个中间结果容器进行合并,因为在finnish中只会接收一个参数。如果不需要合并,则不会执行conbiner方法
         *  4、	Function<A, R> finishaer(); --> 接收一个参数,返回一个值。这是最后的归集操作,方法接收的参数就是accumulator或者是combiner产生的结果,也就是一个中间的结果集。中间结果集合通过finisher方法输出最终结果
         */

所以Collector只是规定一种元素运算方式,或者说是一种运算规范,具体的运算内容可以自定义。


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) {
        Objects.requireNonNull(supplier);
        Objects.requireNonNull(accumulator);
        Objects.requireNonNull(combiner);
        Objects.requireNonNull(finisher);
        Objects.requireNonNull(characteristics);
        Set<Characteristics> cs = Collectors.CH_NOID;
        if (characteristics.length > 0) {
            cs = EnumSet.noneOf(Characteristics.class);
            Collections.addAll(cs, characteristics);
            cs = Collections.unmodifiableSet(cs);
        }
        return new Collectors.CollectorImpl<>(supplier, accumulator, combiner, finisher, cs);
}

of方法返回的是一个CollectorImpl类。CollectorImpl是Collector中的一个静态内部类。这样做的原因主要是使用者不需要自己去定义实现类,然后再进行创建,减少使用者的工作量,同时又能够使代码更简洁优雅。

Collector的构造函数接收5个参数,前面四个(supplier,accumulator,combiner,finisher),这四个参数分别对应上面介绍的四个方法。最后一个参数使用来控制Collector的执行方式的。

1、  CONCURRENT  //将会以并行的方式进行操作

2、  UNORDERED   //不保证输出结果的顺序(没理解)

3、  IDENTITY_FINISH  //恒等函数,当传入这个值时,finisher函数将不会执行,而直接返回结果


IDENTITY_FINISH: 传入这个参数,finisher函数将会被认为是一个恒等函数。即:输出类型与输入类型完全一致。此时将不会再执行finisher方法,而是将中间结果集合进行强制类型转换得到最后的结果。源代码如下:

collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)
               ? (R) container
               :collector.finisher().apply(container)

CONCURRENT:

1、  传入这个参数,同时调用parallel()方法,supplier方法只会执行一次,并且会创建多个线程操作这个集合。

2、  不传入这个参数,同时调用parallel()方法,将会执行supplier()方法多次,创建多个线程操作多个容器。

3、  传入这个参数,不调用parallel()方法,supplier方法只会执行一次,不会创建多个线程,使用主线程执行操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值