Java 为什么标识值必须是Stream.reduce中组合器函数的标识?
我正在学习Java 8,它说: 更正式地说,标识值必须是组合器函数的标识。这意味着对于所有u,combiner.apply(标识,u)等于u。此外,组合器函数必须是关联的,并且必须与累加器函数兼容:对于所有u和t,combiner.apply(u,acculator.apply(identity,t))必须等于acculator.apply(u,t) 我不明白为什么标识值必须是组合器函数的标识。我认为“组合器函数必须是关联的,并且必须是兼容的”足以产生相同的结果,无论流是串行的还是并行的 例如,我有一个流,它有四个元素Java 为什么标识值必须是Stream.reduce中组合器函数的标识?,java,java-8,java-stream,Java,Java 8,Java Stream,我正在学习Java 8,它说: 更正式地说,标识值必须是组合器函数的标识。这意味着对于所有u,combiner.apply(标识,u)等于u。此外,组合器函数必须是关联的,并且必须与累加器函数兼容:对于所有u和t,combiner.apply(u,acculator.apply(identity,t))必须等于acculator.apply(u,t) 我不明白为什么标识值必须是组合器函数的标识。我认为“组合器函数必须是关联的,并且必须是兼容的”足以产生相同的结果,无论流是串行的还是并行的 例如,
e1、e2、e3、e4
。如果是串行流,则结果是identity
ace1
ace2
ace3
ace4
(ac表示累加器功能)。如果它是一个并行流,那么这四个元素可以分成两部分,[e1,e2]
和[e3,e4]
,因此结果是(identity
ace1
ace2
)co(identity
ace3
ace4
)
如果给定“组合器功能是关联的并且与累加器功能兼容”,我们可以推断“identity
ace1
ace2
ace3
ace4
”等于“(identity
ace1
ace2
)co(identity
ace3
ace4
)”:
那么,为什么标识值必须是组合器函数的标识呢
相关问题:
optionant sum=Arrays.stream(新的int[]{0,2,6}).reduce((a,b)->a+b);
但是,如果这样做,空流将不会返回有效的结果,因为缩减操作“不知道”0
是您定义的“求和”操作的中性元素。在数学术语中,您定义的是该操作的标识元素,因此在该操作根本不适用的情况下会有回退.您可以这样直观地描述操作:
缩减=op(标识、a、b、c…)
这就是为什么您会收到Optionant,这意味着可能不会计算任何整数值
对于乘法,恒等式为
1
,对于求和0
等。由于恒等式必须为中性,因此严格意义上它不是回退,因为回退可以是任何值,包括-1或任何其他值(不得为数字值)因此,Optionant提供了一个很好的替代方案,因为使用optional,您可以应用或(fallback)
方法,该方法不需要是还原的中性元素。写“标识值必须是组合器函数的标识”或“标识值必须是累加器函数的标识”,因为组合器函数和累加器函数必须兼容。但必须至少做出一条语句,而且由于文档只做出一条语句(无冗余),我不认为有问题。@Holger您如何定义“标识值是累加器功能的标识”?标识值的类型为U
,流中的元素的类型为T
。为什么我们需要“标识值必须是组合器功能的标识”或“标识值必须是累加器功能的标识”?1。)累加器函数的第一个参数的类型与标识值的类型相同。2)您基本上假设该值的行为符合预期,但询问我们为什么需要定义该值必须符合预期。如果您认为没有必要将其定义为标识值,为什么要继续编写在你的例子中“identity
”?用任意值替换它,比如说e0
。然后,解释为什么“e0
ace1
ace2
ace3
ace4
”等于“(e0
ace1
acace2
)co(e0
acac)乔恩·汉森也许有帮助,因为为累加器指定的关联性约束产生了类似的混淆。它有助于考虑,即使在这个问题中,已经引述了什么,组合函数必须是“兼容的”。使用累加器函数。从概念上讲,只有一个归约函数,就像其他两个reduce
方法一样,但这三个参数重载允许优化map/reduce的特例。第一个参数必须是归约函数的一个标识元素。@Holger我不困惑,我只是addressing使用语句“identity值必须是累加器函数的标识”。这是不可能的,甚至是没有意义的,因为JasonLaw还指出,类型不匹配。
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)