Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the accumulator in Stream::reduce a BiFunction and not a BinaryOperator like the combiner?

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>?

like image 976
heaprc Avatar asked Dec 08 '16 09:12

heaprc


People also ask

What does reduce () method does in stream?

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.

What is combiner In reduce?

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.

What happens if a reduction operation has no identity element?

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.

What is combiner in Java?

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.


1 Answers

<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.

like image 107
Eran Avatar answered Sep 21 '22 00:09

Eran