collect(supplier, accumulator, combiner)的combiner的组合顺序在哪里定义?
Java API 文档声明 collect
方法的 combiner
参数必须是:
The Java API documentations states that the combiner
parameter of the collect
method must be:
用于组合两个值的关联、无干扰、无状态函数,必须与累加器函数兼容
an associative, non-interfering, stateless function for combining two values, which must be compatible with the accumulator function
一个combiner
是一个BiConsumer
,它接收两个R
类型的参数并返回void
.但是文档没有说明我们是否应该将元素组合到第一个或第二个参数中?
A combiner
is a BiConsumer<R,R>
that receives two parameters of type R
and returns void
. But the documentation does not state if we should combine the elements into the first or the second parameter?
例如,以下示例可能会给出不同的结果,具体取决于组合顺序为:m1.addAll(m2)
或 m2.addAll(m1)
.
For instance the following examples may give different results, depending on the order of combination be: m1.addAll(m2)
or m2.addAll(m1)
.
List<String> res = LongStream
.rangeClosed(1, 1_000_000)
.parallel()
.mapToObj(n -> "" + n)
.collect(ArrayList::new, ArrayList::add,(m1, m2) -> m1.addAll(m2));
我知道在这种情况下我们可以简单地使用方法句柄,例如 ArrayList::addAll
.然而,在某些情况下需要 Lambda,我们必须以正确的顺序组合项目,否则在并行处理时可能会得到不一致的结果.
I know that in this case we could simply use a method handle, such as ArrayList::addAll
. Yet, there are some cases where it is required a Lambda and we must combine the items in the correct order, otherwise we could get an inconsistent result when processing in parallel.
这在 Java 8 API 文档的任何部分中都有声明吗?还是真的没关系?
Is this claimed in any part of the Java 8 API documentation? Or it really doesn't matter?
推荐答案
好像文档中没有明确说明.但是,流 API 中有一个 ordering 概念.流可以订购或不订购.如果源拆分器是无序的(例如,如果流源是 HashSet
),它可能从一开始就是无序的.或者如果用户明确使用 unordered()
操作,流可能会变得无序.如果流是有序的,那么收集过程也应该是稳定的,因此,我猜,假设对于有序流,combiner
以严格的顺序接收参数.但是,对于无序流,不能保证.
Seems that this is not explicitly stated in the documentation. However there's an ordering concept in streams API. Stream can be either ordered or not. It may be unordered from the very beginning if source spliterator is unordered (for example, if the stream source is HashSet
). Or the stream may become unordered if user explicitly used unordered()
operation. If the stream is ordered, then collection procedure should also be stable, thus, I guess, it's assumed that for ordered streams the combiner
receives the arguments in the strict order. However it's not guaranteed for an unordered stream.
相关文章