Reducing
The sum method is a type of terminal operation known as a reducing operation: it takes a set of values and reduces them to an aggregate value. You could also have implemented the sum functionality via the general purpose reduce terminal operation:
l.stream()
.filter(p -> p%2==1)
.mapToInt(p -> p * p)
.reduce((a, b) -> a + b)
The reduce method starts by passing the first two elements in the stream to the lambda expression provided. The result of this operation is then passed to the lambda expression along with the third element, and so on until the elements have all been processed. The following is a print out of the values passed to the reduce lambda expression:
a = 25, b = 3025
a = 3050, b = 529
a = 3579, b = 49
a = 3628, b = 2025
(There are 5 odd numbers, so the expression is invoked 4 times).
The reduce method returns an instance of OptionalInt, because the filter method could have potentially removed all elements from the Stream.
The reduce operation accepts a lambda expression conforming to the BinaryOperator functional interface. This interface has a method that accepts two parameters and returns a single parameter of the same type:
Due to the power of auto-generated interfaces, you could therefore have reused one of the new static helper methods added to Integer (and the other number wrapper types) in Java 8:
public static int sum(int a, int b)
As follows:
l.stream()
.filter(p -> p%2==1)
.mapToInt(p -> p * p)
.reduce(Integer::sum)
Notice that the sum method is static, therefore you don’t need an instance of Integer to invoke the sum method.
The reduce operation can also accept an optional first parameter representing the initial value of the aggregation:
l.stream()
.filter(p -> p%2==1)
.mapToInt(p -> p * p)
.reduce(100, (a, b) -> a + b)
This example will return 100 more than the previous example.
If omitted, this uses the default value for the data-type returned, e.g. 0 for numbers.