java - 为什么 Java 的 Stream.reduce 方法采用标识元素而不是默认结果?

标签 java java-stream

Stream 有 3 个 reduce 方法:

  1. Optional<T> reduce​(BinaryOperator<T> accumulator)
  2. T reduce​(T identity,BinaryOperator<T> accumulator)
  3. <U> U reduce​(U identity,BiFunction<U,​T,​U> accumulator,BinaryOperator<U> combiner)

方法 2 和 3 采用标识元素。

如 Oracles 中所述 doc on reduction : "标识元素既是缩减的初始值,也是流中没有元素时的默认结果。"

我理解作为默认值的目的:这样方法就不必返回 Optional。但是为什么要使用恒等元作为归约的初始值呢?它的目的是什么?为什么它不像第一个 reduce 方法那样从流的第一个元素开始?

或者换个方式问:为什么第二个和第三个reduce方法不取默认值,而是取一个标识元素?这肯定会增加灵 active ,因为默认值不必是运算符的标识值。

最佳答案

请特别注意第三种方法:这里的 accumulation(用词不当,真的;这是一个 conclist 而不是 conslist,但我希望你能理解这里的意思)与流是不同的类型。

例如,你有一个字符串流,你将它缩减为一个计算字符串长度的操作;累加是作为一个整数完成的。

在这种情况下,明显的“初始/默认值”是 0,您不能使用“流中的第一个值”;那是一个字符串而不是一个整数。

请注意这是如何与类型匹配的:在第三个签名中,初始/默认值的类型是“U”,而流是 T 对象的流。

即使对于第一个签名,如果流不为空,您有时也不想“只是”以随机开始(流不一定是有序的;“第一”对各种情况没有意义流,因此,“某些值”是比“第一个值”更好的思考方式,这已经是一个问题)来自流的值,但具有一些已知值。

那么,让我们回顾一下:

  1. 如果您想使用“嘿,流中的任意元素都可以用作初始值,但是,我想指定一个特定的默认值以避免可选”,那么这很简单: stream.reduce(accumulatorFunction).orElse(defaultValue) 会给你这个。

  2. 如果您想使用“我有一个特定值作为初始值”,那么,我很难想象如果零元素在流,所以,您只需使用第二种形式。

  3. 如果您使用与流来源不同的类型作为累积值,则必须使用第 3 种形式并且必须指定初始值,因为流中的任意项不能作为一个;它会有错误的类型。与之前的一样:如果您指定一个明确的初始值,那是..在空流的情况下几乎总是适当的默认值。

因此它们都是有道理的。

关于java - 为什么 Java 的 Stream.reduce 方法采用标识元素而不是默认结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59636780/

相关文章:

java - netbeans 和 Apache Derby Embedded + spring

java - 将 Java 代码翻译为 C

java - 安装莱宁根

loops - 如何将for循环转换为stream循环

Java8 流无法解析变量

java - 为什么即使在设置 JPanel 的大小后,我的框布局也会更改大小

java - 拆分为多个字符

java - 在 Java8 中使用 lambda 排序和创建映射

java - IntelliJ : How to autocomple AND import statically Collectors. 列表()

java - 使用 parallelStream().reduce() 时的错误结果