gpt4 book ai didi

java - 难道不能保证从列表派生的并行流总是表现得像它的顺序对应物一样,提供相同的、可预测的输出吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:19:46 28 4
gpt4 key购买 nike

以下代码打印 true 100 次:

for(int i=0; i<100; i++) {
String s2 = Arrays.asList("A", "E", "I", "O", "U").parallelStream().reduce("x", String::concat, String::concat);
System.out.println("xAxExIxOxU".equals(s2));
}

当然,100 次并不是保证。但是,即使此处使用的身份不符合 doc 的要求“...对于所有 u,combiner.apply(identity, u) 等于 u”,这似乎不是吗? , 我们仍然可以说从列表或任何其他固有有序结构派生的并行流将表现得像 reduce() 中的顺序流一样返回相同的输出?

最佳答案

Javadoc for the Stream.reduce function with an identity argument说:

The identity value must be an identity for the accumulator function. This means that for all t, accumulator.apply(identity, t) is equal to t.

这里显然不是这种情况 - "x".concat(anything) 不等于 anything。此处唯一有效的标识值是 ""

如果您已经测试了您问题的标题 的前提 - 通过查看非并行操作返回的内容 - 您会发现您的标题的答案是“否” - 因为非并行流为您的归约操作返回 "xAEIOU"

如果您将标识值从 "x" 更改为 "",那么答案将是“是的,有这样的保证,因为您的 reduce 函数是associative 并且对身份值的约束也得到满足。”

即使您修改了标题,答案也很明确:

您通过提供一个不是您的 reduce 函数的标识值的值作为标识值来破坏 reduce 函数的契约。因此,由于您违反了 reduce 方法的约定,因此所有保证均无效。

创建一个不成立的案例很容易;就像 Holger 已经指出的那样,让您的列表更大:

List<String> list = new ArrayList<>();
for (int i = 0; i < 500; i++) {
list.add("A");
}
String s2 = list.parallelStream().reduce("x", String::concat, String::concat);
System.out.println(s2);
if (s2.length() != list.size() * 2) {
System.out.println("Bad s2 size");
}

关于java - 难道不能保证从列表派生的并行流总是表现得像它的顺序对应物一样,提供相同的、可预测的输出吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56510384/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com