为什么Collector接口的组合器与重载的collect方法不一致?

Mig*_*boa 21 java java-8 java-stream

有一个重载方法,collect()Stream<T>与以下签名的接口中:

<R> R collect(Supplier<R> supplier,
          BiConsumer<R,? super T> accumulator,
          BiConsumer<R,R> combiner)
Run Code Online (Sandbox Code Playgroud)

还有另一个版本collect(Collector<? super T,A,R> collector),它接收具有前三个功能的对象.Collector对应的接口的属性combiner具有签名BinaryOperator<A> combiner().

在后一种情况下,Java API 8声明:

组合器函数可以将状态从一个参数折叠到另一个参数并返回该参数,或者可以返回新的结果容器.

为什么前collect一种方法也没有收到BinaryOperator<R>呢?

Bri*_*etz 19

"内联"(3-arg)版本collect是专为您已经"躺着"的这些功能而设计的.例如:

ArrayList<Foo> list = stream.collect(ArrayList::new, 
                                     ArrayList::add,
                                     ArrayList::addAll);
Run Code Online (Sandbox Code Playgroud)

要么

BitSet bitset = stream.collect(BitSet::new, 
                               BitSet::set,
                               BitSet::or);
Run Code Online (Sandbox Code Playgroud)

虽然这些仅仅是激励性的例子,但我们对类似的现有构建器类的探索是,现有组合器候选者的签名更适合转换为BiConsumer而不是BinaryOperator.提供你所要求的"灵活性"会使这种过载在它被设计为支持的情况下变得不那么有用 - 这就是当你已经有了功能时,你不想做(你不想做)或者学习制作)收藏家只是为了收集它们.

另一方面,收集器具有更广泛的用途,因此具有额外的灵活性.


Hol*_*ger 5

请记住, 的主要目的Stream.collect()是支持Mutable Reduction。对于此操作,累加器组合器这两个函数都旨在操作可变容器,并且 don\xe2\x80\x99t 需要返回一个值。

\n\n

因此,不坚持返回值要方便得多。正如布莱恩·戈茨指出的,这一决定允许重用许多现有的容器类型及其方法。如果无法直接使用这些类型,整个三参数collect方法将毫无意义。

\n\n

相反,Collector接口是此操作的抽象,支持更多用例。最值得注意的是,您甚至可以通过. 在这种情况下,必须有Collector有一个返回值,因为值对象本身不得被修改。

\n\n

当然,它并不意味着用来stream.collect(Collectors.reducing(\xe2\x80\xa6))代替stream.reduce(\xe2\x80\xa6)相反,当组合收集器时,这种抽象会很方便,例如groupingBy(\xe2\x80\xa6,reducing(\xe2\x80\xa6)).

\n