Stream.reduce(BinaryOperator<T> accumulator) 如何初始化?

How does Stream.reduce(BinaryOperator<T> accumulator) initialized?

以下代码无需初始化 reduce 操作即可完美运行。

int sum=Stream.of(2,3).reduce((Integer a,Integer b)->a+b).get(); // sum = 5
int sum=Stream.of(2,3).reduce((Integer a,Integer b)->a*b).get(); // sum = 6

它怎么知道第一个累加器是 +,因此它应该初始化为一个新的 sum = 0,而第二个累加器是 *,因此它应该初始化为一个新总和 = 1?

只要您的流具有一个或多个元素,您就不需要标识值。第一个缩减returns2+3,相当于0+2+3。第二个returns2*3,相当于1*2*3.

1 个参数 reduce 不是以标识值(0 或 1)开头。它仅对流中的值进行操作。如果您查看 javadoc,它甚至会显示等效代码:

 boolean foundAny = false;
 T result = null;
 for (T element : this stream) {
     if (!foundAny) {
         foundAny = true;
         result = element;
     }
     else
         result = accumulator.apply(result, element);
 }
 return foundAny ? Optional.of(result) : Optional.empty();

这是它的 API 规格:

Optional<T> java.util.stream.Stream.reduce(BinaryOperator<T> accumulator)

其中 returns: 一个可选的描述减少的结果

根据其javadoc,等效代码为:

boolean foundAny = false;
T result = null;
for (T element : this stream) {
    if (!foundAny) {
        foundAny = true;
        result = element;
    }
    else
        result = accumulator.apply(result, element);
}
return foundAny ? Optional.of(result) : Optional.empty();

三种情况:

  1. 流中没有元素:return Optional.empty()
  2. 一个元素:只是 return 元素,根本不应用累加器。
  3. 两个或更多元素:将累加器应用于所有元素并 return 结果。

此 reduce 方法的更多示例:

// Example 1: No element
Integer[] num = {};
Optional<Integer> result = Arrays.stream(num).reduce((Integer a, Integer b) -> a + b);
System.out.println("Result: " + result.isPresent()); // Result: false

result = Arrays.stream(num).reduce((Integer a, Integer b) -> a * b);
System.out.println("Result: " + result.isPresent()); // Result: false

// Example 2: one element   
int sum = Stream.of(2).reduce((Integer a, Integer b) -> a + b).get();
System.out.println("Sum: " + sum); // Sum: 2

int product = Stream.of(2).reduce((Integer a, Integer b) -> a * b).get();
System.out.println("Product: " + product); // Product: 2

// Example 3: two elements
sum = Stream.of(2, 3).reduce((Integer a, Integer b) -> a + b).get();
System.out.println("Sum: " + sum); // Sum: 5

product = Stream.of(2, 3).reduce((Integer a, Integer b) -> a * b).get();
System.out.println("Product: " + product); // Product: 6