In Stream reduce method, must the identity always be 0 for sum and 1 for multiplication?

前端 未结 7 797
执念已碎
执念已碎 2020-11-29 06:05

I proceed with java 8 learning.

I have found an interesting behavior:

let\'s see code sample:

// identity value and accumulator and combiner         


        
相关标签:
7条回答
  • 2020-11-29 06:52

    In addition to the excellent answers posted before it should be mentioned that if you want to start summing with something other than zero, you can just move the initial addend out of the stream operation:

    Integer summaryAge = Person.getPersons().stream()
            //.parallel()  //will return no surprising result
            .reduce(0, (intermediateResult, p) -> intermediateResult + p.age,
                        (ir1, ir2) -> ir1 + ir2)+1;
    

    The same is possible for other reduction operations. For example, if you want to calculate the product starting with 2 instead of doing wrong .reduce(2, (a, b) -> a*b), you can do .reduce(1, (a, b) -> a*b)*2. Just find the real identity for your operation, move the "false identity" outside and you will get the correct result both for sequential and parallel case.

    Finally note that there's more efficient way to solve your problem:

    Integer summaryAge = Person.getPersons().stream()
            //.parallel()  //will return no surprising result
            .collect(Collectors.summingInt(p -> p.age))+1;
    

    or alternatively

    Integer summaryAge = Person.getPersons().stream()
            //.parallel()  //will return no surprising result
            .mapToInt(p -> p.age).sum()+1;
    

    Here the summation is performed without boxing on every intermediate step, thus it can be much faster.

    0 讨论(0)
提交回复
热议问题