Deciphering Stream reduce function

alwayscurious :

Why are both c1 and c2 are not seen as two Strings but instead one String and one Integer?

Arrays.asList("duck","chicken","flamingo","pelican")
            .stream()
            .reduce(0,
                    (c1, c2) -> c1.length() + c2.length(),
                    (s1, s2) -> s1 + s2);
Ousmane D. :

There are three variations of the reduce method, which differ by their signatures and return types. if you look at the overload for reduce which has this signature:

reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)

As you can see from the method signature this overload of reduce has 3 parameters the identity, accumulator and a combiner. The identity value is the initial value you've passed into reduce i.e (0), we then have the accumulator which basically incorporates an additional element into a result and finally, the combiner whos job is to combine the two values provided.

so you ask:

Why are both c1 and c2 are not seen as two Strings but instead one String and one Integer?

The first argument to BiFunction is U which in your case is Integer so, therefore, the type used for the identity value must be the same type of the first argument as well as the return type of the accumulator function (BiFunction).

That aside, you'll need to change this:

(c1, c2) -> c1.length() + c2.length()

to this:

 (c1, c2) -> c1 + c2.length()

it's important to note that the combiner function (s1, s2) -> s1 + s2 will not be called at all. Reason being that this specific overload was designed to be used with parallelStream, so in order for a combiner to work, a stream must be parallel. Otherwise, just the accumulator function will be called.

as an side, your full code can be simplified to:

int result = Stream.of("duck","chicken","flamingo","pelican")
                   .reduce(0,
                   (c1, c2) -> c1 + c2.length(),
                   (s1, s2) -> s1 + s2);

or even better if you want to avoid the overhead of boxing/unboxing of reduce:

int result = Stream.of("duck", "chicken", "flamingo", "pelican")
                   .mapToInt(String::length)
                   .sum();

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=469732&siteId=1