Jas*_*Law 5 java java-8 java-stream
我正在学习Java 8,在包摘要的Reduction操作部分中java.util.stream,它说:
更正式地说,标识值必须是组合器函数的标识。这意味着对于所有 u,combiner.apply(identity, u) 等于 u。此外,组合器函数必须是关联的,并且必须与累加器函数兼容:对于所有 u 和 t,combiner.apply(u,accumulator.apply(identity, t)) 必须是 equals() 到accumulator.apply(u, t)。
我不明白为什么标识值必须是组合器函数的标识。我认为“组合器函数必须是关联的并且必须是兼容的”足以产生相同的结果,无论流是串行还是并行。
例如,我有一个包含四个元素的流e1, e2, e3, e4。如果是串行流,则结果为identityac e1ac e2ac e3ac e4(ac表示累加器函数)。如果是并行流,则四个元素可以分成两部分,[e1, e2]和[e3, e4],所以结果是 ( identityac e1ac e2) co ( identityac e3ac e4)。
如果给定“组合器函数是关联的并且与累加器函数兼容”,我们可以推断“ identityac e1ac e2ac e3ac e4”等于“( identityac e1ac e2) co ( identityac e3ac e4)”:
identity ac e1 ac e2 ac e3 ac e4
= (identity ac e1 ac e2 ac e3) co (identity ac e4) // because of compatibility
= (identity ac e1 ac e2) co (identity ac e3) co (identity ac e4) // because of compatibility
= (identity ac e1 ac e2) co ((identity ac e3) co (identity ac e4)) // because of associative property
= (identity ac e1 ac e2) co ((identity ac e3) ac e4) // because of compatibility
= (identity ac e1 ac e2) co (identity ac e3 ac e4)
Run Code Online (Sandbox Code Playgroud)
那么,为什么恒等值必须是组合器函数的恒等呢?
相关问题:
我不明白为什么标识值必须是组合器函数的标识。
它必须是,因为否则如果提供的流为空,则不会生成任何结果。但同一性约简的结果不是可选的。您可以定义没有标识的Java 8 缩减:
OptionalInt sum = Arrays.stream(new int[] { 0, 2, 6 }).reduce((a, b) -> a + b);
Run Code Online (Sandbox Code Playgroud)
但是,如果您这样做,空流将不会返回有效结果,因为归约操作不“知道”这0是您定义的“求和”操作的中性元素。在数学术语中,您正在定义操作的单位元素,以便在操作根本不适用的情况下有后备。直观地你可以这样描述操作:
减少 = op(身份, a, b, c ...)
这就是为什么您会收到一个OptionalInt,这意味着可能没有计算出任何整数值。
对于乘法,恒等式为1,对于和等0。由于恒等式必须是中性的,所以它不是最严格意义上的后备,因为后备可以是任何值,包括 -1 或任何其他值(不得是数字) )。因此,OptionalInt 提供了一个很好的替代方案,因为使用可选项,您可以应用该or(fallback)方法,该方法不需要是归约的中性元素。
| 归档时间: |
|
| 查看次数: |
461 次 |
| 最近记录: |