Stream reduce() 要求究竟需要什么?
在并行流上使用该操作时,OCP考试手册指出,论点必须遵守某些原则。这些原则如下:reduce()
reduce()
- 必须定义标识,以便对于流 u 中的所有元素,combiner.apply(标识,u) 等于你。
- 累加器运算符 op 必须是关联且无状态的,因此等于 。
(a op b) op c
a op (b op c)
- 组合器运算符还必须是关联和无状态的,并且与标识兼容,以便对于 all of 和 等于 。
u
t
combiner.apply(u, accumulator.apply(identity, t))
accumulator.apply(u,t)
本书给出了两个例子来说明这些原则,请参阅下面的代码:
关联示例:
System.out.println(
Arrays.asList(1, 2, 3, 4, 5, 6)
.parallelStream()
.reduce(0, (a, b) -> (a - b)));
书中对此有何描述:
它可能会输出 -21、3 或某些其他值,因为累加器函数违反了关联性属性。
身份要求的示例:
System.out.println(
Arrays.asList("w", "o", "l", "f")
.parallelStream()
.reduce("X", String::concat));
书中对此有何描述:
如果我们使用不是真正标识值的标识参数,则可以看到其他问题。它可以输出.作为并行过程的一部分,标识应用于流中的多个元素,从而产生非常意外的数据。
XwXoXlXf
我不明白这些例子。以累加器为例,累加器从哪个开始,然后是 哪个是 ,然后依此类推一直到 。我理解,因为生成的数组列表不同步,结果可能是不可预测的,因为可能存在争用条件等,但为什么累加器不是关联的呢?也不会造成不可预测的结果吗?我真的看不出示例中使用的累加器有什么问题,以及为什么它不是结合的,但话说回来,我仍然不完全理解“结合原理”是什么意思。0 - 1
-1
-1 - 2
-3
-6
-21
(a+b)
我也不明白身份的例子。我知道结果可能是如果4个单独的线程同时开始与标识一起累积,但这与标识参数本身有什么关系?那么,究竟使用什么才是合适的身份呢?XwXoXlXf
我想知道是否有人能就这些原则对我有更多的启发。
谢谢