Why is the accumulator argument in the Stream::reduce
method a BiFunction
and not a BinaryOperator
like the combiner argument.
Why is its type BiFunction<U, ? super T, U>
? Why T
? Should it be BiFunction<U, ? extends U, U>
?
Reducing is the repeated process of combining all elements. reduce operation applies a binary operator to each element in the stream where the first argument to the operator is the return value of the previous application and second argument is the current stream element.
Combiner – a function used to combine the partial result of the reduction operation when the reduction is parallelized or when there's a mismatch between the types of the accumulator arguments and the types of the accumulator implementation.
Identity is the default result of reduction if there are no elements in the stream. That's the reason, this version of reduce method doesn't return Optional because it would at least return the identity element. Ignoring this rule will result in unexpected outcomes.
A Combiner, also known as a semi-reducer, is an optional class that operates by accepting the inputs from the Map class and thereafter passing the output key-value pairs to the Reducer class. The main function of a Combiner is to summarize the map output records with the same key.
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
The accumulator is a function that adds an element of the Stream
(whose type is denoted by T
) to the intermediate result of the reduce
operation (whose type is denoted by U
) and returns an updated result (also of type U
).
Therefore you can't define it as a BinaryOperator
, where the operands and result are all of the same type.
For example, you might pass as the accumulator in a reduce
call a BiFunction<Integer,String,Integer>
which is applied on a Stream<String>
and produces the sum of the lengths of all the elements. You can't use a BinaryOperator<Integer>
or a BinaryOperator<String>
for that.
On the other hand, the combiner takes two intermediate results (both of the same type U
) and merges them into a result whose type is also U
. Therefore a BinaryOperator<U>
(which extends BiFunction<U,U,U>
) can be used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With