java - Java流如何减少累加器参数是关联的
问题描述
问题是关于
java.util.stream.Stream.reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner)
方法。
从 API 文档:
累加器——一种关联的、非干扰的、无状态的函数,用于将附加元素合并到结果中
现在,联想的定义是:
(a op b) op c = a op (b op c) for all a, b, c
正如我们所看到的,上面的定义需要一个 BinaryOperator,而不仅仅是一个 BiFunction,因为a op b
requires b
of typeT
而b op c
requires b
of type U
。如果U
和T
是不同的,这是不可能的。
我的问题
如何为不是 BinaryOperator 的 BiFunction 制定关联的定义?
更新
我已向 Oracle 提交了关于此问题的错误,内部审核 ID:9063337
我将根据 Oracle 的反馈更新问题。
解决方案
注意文档:
此外,
combiner
功能必须与accumulator
功能兼容;对于所有u
和t
,必须满足以下条件:combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
而==
不是字面意思,而是“等价的结果”</sup>
所以事实上,我们对关联性的约束要强得多accumulator
,因为它必须与 兼容combiner
,后者是一个关联函数。
还有 API 注意:
许多使用这种形式的归约可以通过 map 和 reduce 操作的显式组合更简单地表示。accumulator 函数充当融合的映射器和累加器,有时比单独的映射和归约更有效,...</p>
当accumulator
函数是融合映射和归约函数时,只有归约部分必须是关联的。当您要测试该部分时,只需测试该combiner
函数是否满足关联性约束以及是否combiner
以accumulator
指定方式兼容。如果两者都被证明,则accumulator
' 的归约部分的结合性也被证明了。
虽然 API Note 说“使用这种形式进行了许多归约”,但实际上所有这些都可以表示为 map 和 reduce 操作的显式组合,当我们忽略效率时,由于指定的约束:
Function<T,U> mappingFunc = t -> accumulator.apply(identitiy, t);
U result = streamOfT.map(mappingFunc).reduce(identitiy, combiner);
这result
必须等同于,例如,一个典型的顺序评估的结果streamOfT.reduce(identitiy, accumulator, combiner)
,它根本不使用combiner
。
我们可以为关联性制定狭窄的测试用例为
U u1 = accumulator.apply(accumulator.apply(identitiy, t1), t2);
U u2 = combiner.apply(accumulator.apply(identitiy, t1), accumulator.apply(identitiy, t2));
其中u1
和u2
必须是等价的结果,以及
U u1 = accumulator.apply(accumulator.apply(accumulator.apply(identitiy, t1), t2), t3);
U u2 = combiner.apply(accumulator.apply(identitiy, t1),
accumulator.apply(accumulator.apply(identitiy, t2), t3));
推荐阅读
- reactjs - 反应 JSX 问题
- python - 如何直接在 Pandas DataFrame 中的 PDF 上计算统计指标?
- javascript - 嵌套的 promise.all
- prolog - Prolog - 数字到单词
- python - 如何从 BeautifulSoup 中的“get_text()”输出中删除一些文本
- javascript - 通过片段标识符或视图规范嵌入在 HTML 中的外部 SVG 文档的非标准视图:如何操作 viewBox?
- python - 如何将可训练参数添加到 Tensorflow2 Keras 模型损失函数中
- vue-router - 使用不同参数值调用两次的动态路由不会第二次执行挂载方法
- for-loop - 为什么这个嵌套循环在 Google Apps 脚本(表格/管理员)中不起作用并且没有抛出错误?
- c++11 - 从 EEPROM 读取时,使用具有虚拟继承的结构是个坏主意吗?(阿杜诺)