带有collect方法()的parallelStream

问题描述 投票:0回答:1

我试图理解为什么当我在下面的代码片段中从 y.addAll(x) 更改为 x.addAll(y) 时会有不同:

List<Integer> result = List.of(1, 2)
    .parallelStream() 
    .collect(
        ArrayList::new,
        (x, y) -> x.add(y),
        (x, y) -> y.addAll(x)
    );
System.out.println(result);

我知道,当我使用parallelStream()时,一次会运行多个线程。

collect() 有三个参数;前两个参数我理解。使用第三个参数,我知道 x,y 是子流,它们是 ArrayList,但我不明白为什么每种情况下的结果都不同。我希望他们是一样的。

  • (x, y) -> y.addAll(x) // 输出:[1]

  • (x, y) -> x.addAll(y) // 输出:[1, 2]

java java-11
1个回答
1
投票

来自

Stream#collect
的Javadocs(特别是最后一个参数,强调我的):

combiner - 一个关联的、互不干扰的、无状态的函数,它接受两个部分结果容器并将它们合并,它必须与累加器函数兼容。组合器函数必须将第二个结果容器中的元素折叠到第一个结果容器中。

因此,该方法的约定指定您必须将 lambda 的第二个参数合并到第一个参数中。

如果您执行

(x, y) -> x.addAll(y)

,它将按照合同将

y
的所有元素添加到
x
中。但是,对于
(x, y) -> y.addAll(x)
,您将其添加到第二个元素,导致
y
的元素未添加到
x
,然后这些元素在结果中丢失。
    

© www.soinside.com 2019 - 2024. All rights reserved.