Note: Some of the examples are contrived for demonstration. In some instances a simple .sum()
could have been used.
The big difference, imo, is that the third form has a BiFunction
as a second argument instead of a BinaryOperator
. So you can use the third form to change the result type. It also has a BinaryOperator
as a combiner to combine the different results from parallel operations.
Generate some data
record Data(String name, int value) {}
Random r = new Random();
List<Data> dataList = r.ints(1000, 1, 20).mapToObj(i->new Data("Item"+i, i)).toList();
No parallel operation but different types. But the third argument is required so just return the sum.
int sum = dataList.stream().reduce(0, (item, data) -> item + data.value,
(finalSum, partialSum) -> finalSum);
System.out.println(sum);
prints
10162
The second form. Use map to get the value to be summed. BinaryOperator
used here since types are the same and no parallel operation.
sum = dataList.stream().map(Data::value).reduce(0, (sum1,val)->sum1+val);
System.out.println(sum); // print same as above
This shows the same as above but in parallel. The third argument accumulates partial sums. And those sums are accumulated as the next thread finishes so there may not be a sensible order to the output.
sum = dataList.parallelStream().reduce(0, (sum1, data) -> sum1 + data.value,
(finalSum, partialSum) -> {
System.out.println("Adding " + partialSum + " to " + finalSum);
finalSum += partialSum;
return finalSum;
});
System.out.println(sum);
prints something like the following
Adding 586 to 670
Adding 567 to 553
Adding 1256 to 1120
Adding 715 to 620
Adding 624 to 601
Adding 1335 to 1225
Adding 2560 to 2376
Adding 662 to 579
Adding 706 to 715
Adding 1421 to 1241
Adding 713 to 689
Adding 576 to 586
Adding 1402 to 1162
Adding 2662 to 2564
Adding 4936 to 5226
10162
One final note. None of the Collectors.reducing
methods have a BiFunction
to handle different types. To handle this the second argument is a Function
to act as a mapper so the third argument, a BinaryOperator
can collect the values.
sum = dataList.parallelStream().collect(
Collectors.reducing(0, Data::value, (finalSum, partialSum) -> {
System.out.println(
"Adding " + partialSum + " to " + finalSum);
return finalSum + partialSum;
}));
System.out.println(sum);