java8 stream源码中stream.collect(Collectors.toList()) 传参没有理解

图片说明

Stream的collect方法传入的是Collector接口

图片说明

一般博客介绍都是传入的Collectors.toList()这个方法,源码:

图片说明

问题:

1.我想知道这个toList方法是怎么获取源stream对象的,对象是怎么被转成list的,这个调用过程是怎样的

2.toList()方法的第二个参数是怎么确定List类型的 ,其形参是BiConsumer accumulator,实参是List::add, 实参List类型是如何确定的

1大致代码类似
List toList(stream) {
List result = new List();
while (stream.hasNext())
list.add(next());
return list;
}

2Java编译器有类型推定,collection前面的stream返回值类型可以推定出来,并且得知toList的类型

1.stream对象是上一个方法返回的返回值。
比如

 Stream.of("a", "b", "c").map(String::toUpperCase).collect(Collectors.toList());

调用map的对象是Stream.of返回的,调用collect的对象是map返回的。

2.是由Stream对象确定的。

先看collect方法:

        @Override
    @SuppressWarnings("unchecked")
    public final <R, A> R collect(Collector<? super P_OUT, A, R> collector) {
        A container;
        if (isParallel()
                && (collector.characteristics().contains(Collector.Characteristics.CONCURRENT))
                && (!isOrdered() || collector.characteristics().contains(Collector.Characteristics.UNORDERED))) {
            container = collector.supplier().get();
            BiConsumer<A, ? super P_OUT> accumulator = collector.accumulator();
            forEach(u -> accumulator.accept(container, u));
        }
        else {
            container = evaluate(ReduceOps.makeRef(collector));
        }
        return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)
               ? (R) container
               : collector.finisher().apply(container);
    }

P-OUT可以由stream对象提供,看Stream就知道了。再看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);
            }

P-OUT就传递给了T所以他的类型就确定了。