Stream.reduce(BinaryOperator <t>累加器)是如何初始化的?

时间:2017-05-22 20:41:16

标签: java java-8 java-stream reduce

以下代码完美无需初始化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?

3 个答案:

答案 0 :(得分:8)

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();

答案 1 :(得分:3)

只要您的信息流包含一个或多个元素,您就不需要身份值。第一个缩减返回2+3,相当于0+2+3。第二个返回2*3,相当于1*2*3

答案 2 :(得分:3)

这是它的API规范:

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

返回:an optional描述缩减的结果

根据其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. 一个要素:只返回元素而不应用累加器。
  3. 两个或多个元素:将累加器应用于所有元素并返回结果。
  4. 此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