Why is a combiner needed for reduce method that converts type in java 8

后端 未结 4 2106
野的像风
野的像风 2020-11-27 09:42

I\'m having trouble fully understanding the role that the combiner fulfils in Streams reduce method.

For example, the following code doesn

4条回答
  •  野性不改
    2020-11-27 10:23

    The two and three argument versions of reduce which you tried to use don't accept the same type for the accumulator.

    The two argument reduce is defined as :

    T reduce(T identity,
             BinaryOperator accumulator)
    

    In your case, T is String, so BinaryOperator should accept two String arguments and return a String. But you pass to it an int and a String, which results in the compilation error you got - argument mismatch; int cannot be converted to java.lang.String. Actually, I think passing 0 as the identity value is also wrong here, since a String is expected (T).

    Also note that this version of reduce processes a stream of Ts and returns a T, so you can't use it to reduce a stream of String to an int.

    The three argument reduce is defined as :

     U reduce(U identity,
                 BiFunction accumulator,
                 BinaryOperator combiner)
    

    In your case U is Integer and T is String, so this method will reduce a stream of String to an Integer.

    For the BiFunction accumulator you can pass parameters of two different types (U and ? super T), which in your case are Integer and String. In addition, the identity value U accepts an Integer in your case, so passing it 0 is fine.

    Another way to achieve what you want :

    int length = asList("str1", "str2").stream().mapToInt (s -> s.length())
                .reduce(0, (accumulatedInt, len) -> accumulatedInt + len);
    

    Here the type of the stream matches the return type of reduce, so you can use the two parameter version of reduce.

    Of course you don't have to use reduce at all :

    int length = asList("str1", "str2").stream().mapToInt (s -> s.length())
                .sum();
    

提交回复
热议问题