JAVA8学习笔记--Collectors工厂类分析

1:groupingBy方法分析

public static <T, K, D, A, M extends Map<K, D>>
    Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
                                  Supplier<M> mapFactory,
                                  Collector<? super T, A, D> downstream) {
        //调用传入的下游收集器,
        //产生中间容器进行累加,返回一个A类型的中间容器。
        Supplier<A> downstreamSupplier = downstream.supplier();
        BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
        
        //声明一个新的中间容器累加器,将t作为参数,传入Map<K,A>类型中,Key使用传入一个Function<T>类型的
        //分词器,返回一个K类型的数据作为Map的key,而新建A类型作为key的value容器。组合出一个Map<K,A>类
        //型的中间容器。
        BiConsumer<Map<K, A>, T> accumulator = (m, t) -> {
            K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
            A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
            downstreamAccumulator.accept(container, t);
        };
        
        //声明一个中间容器的Combine函数。这里我们融合的是Map<K,A>;
        BinaryOperator<Map<K, A>> merger = Collectors.<K, A, Map<K, A>>mapMerger(downstream.combiner());
        
        //传入一个Supplier<M> 返回一个M类型的Map作为中间容器,而M继承Map<K,D>,
        //根据上下文推断,我们之前返回的Map是<K,A>类型的,所以这里可以直接进行强转;
        @SuppressWarnings("unchecked")
        Supplier<Map<K, A>> mangledFactory = (Supplier<Map<K, A>>) mapFactory;
	//判断是否使用finisher函数。
        if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
            return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID);
        }
        else {
            //声明一个新的finisher,将中间容器转化成M类型。
            @SuppressWarnings("unchecked")
            Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
            Function<Map<K, A>, M> finisher = intermediate -> {
                intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
                @SuppressWarnings("unchecked")
                M castResult = (M) intermediate;
                return castResult;
            };
            return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID);
        }
    }

2:reducing
为什么要使用数组作为承载的容器,因为数字在lambda表达式中是无法传递的,所以需要使用一个容器进行传递。

public static <T> Collector<T, ?, T>
    reducing(T identity, BinaryOperator<T> op) {
        return new CollectorImpl<>(
                boxSupplier(identity),
                (a, t) -> { a[0] = op.apply(a[0], t); },
                (a, b) -> { a[0] = op.apply(a[0], b[0]); return a; },
                a -> a[0],
                CH_NOID);
    }

    @SuppressWarnings("unchecked")
    private static <T> Supplier<T[]> boxSupplier(T identity) {
        return () -> (T[]) new Object[] { identity };
    }

猜你喜欢

转载自blog.csdn.net/weixin_39781526/article/details/85121763
今日推荐