¿Por qué c1 y c2 no se ven como dos cadenas sino como una String y una Integer?

Arrays.asList("duck","chicken","flamingo","pelican")
            .stream()
            .reduce(0,
                    (c1, c2) -> c1.length() + c2.length(),
                    (s1, s2) -> s1 + s2);
6
alwayscurious 12 nov. 2017 a las 07:08

2 respuestas

La mejor respuesta

Hay tres variaciones de reduce , que se diferencian por sus firmas y tipos de retorno . si observa la sobrecarga de reduce que tiene esta firma:

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

Como puede ver en la firma del método, esta sobrecarga de reduce tiene 3 parámetros la identidad , acumulador y combinador. El valor de identidad es el valor inicial que ha pasado a reduce es decir (0), luego tenemos el acumulador que básicamente incorpora un elemento adicional en un resultado y finalmente, el combinador cuyo trabajo es combinar los dos valores proporcionados.

Entonces preguntas:

¿Por qué tanto c1 como c2 no se ven como dos cadenas sino como una cadena y un entero?

El primer argumento para BiFunction es U, que en su caso es Integer, por lo tanto, el tipo utilizado para el valor de identidad debe ser el mismo tipo de primer argumento, así como el tipo de retorno de la función acumuladora (BiFunction).

Aparte de eso, tendrás que cambiar esto:

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

A esto:

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

Es importante tener en cuenta que la función (s1, s2) -> s1 + s2 del combinador no se llamará en absoluto. La razón es que esta sobrecarga específica fue diseñada para usarse con parallelStream, por lo que para que un combinador funcione, una secuencia debe ser paralela. De lo contrario, solo se llamará a la función de acumulador.

Como un lado, su código completo se puede simplificar a:

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

O incluso mejor si quieres evitar la sobrecarga de boxear / unboxing de reduce:

int result = Stream.of("duck", "chicken", "flamingo", "pelican")
                   .mapToInt(String::length)
                   .sum();
4
Ousmane D. 12 nov. 2017 a las 17:41

Creo que está intentando hacer lo siguiente:

Arrays.asList("duck", "chicken", "flamingo", "pelican")
    .stream()
    .map(c -> c.length())
    .reduce((c1, c2) -> c1 + c2);

Primero, mapee cada String a su longitud, básicamente haciendo la siguiente transformación:

("duck", "chicken", "flamingo", "pelican") -> (4, 7, 8, 7)

Luego, reduzca ese resultado sumando los valores.

1
nicovank 12 nov. 2017 a las 04:27