groupingby - java list group by multiple fields
Contando elementos de una corriente (1)
De hecho, hay varias formas de hacerlo. El que no has mencionado es .collect(groupingBy(x -> x, summingInt(x -> 1)));
Hay algunas diferencias en el rendimiento.
El enfoque n.º 1 va a ser óptimo si hay muy pocos objetos por cubo. En el caso ideal de solo 1 objeto por cubo, termina con el mapa final de inmediato sin necesidad de modificar las entradas. En el peor de los casos de tener una gran cantidad de objetos repetidos, tendrá que hacer mucho boxeo / unboxing.
El Enfoque n. ° 2 se basa en el counting()
de counting()
, que no especifica exactamente cómo debería hacer el recuento. La implementación actual remite a la reducing
pero eso podría cambiar.
El método summingInt
acumulará el recuento en int
en lugar de Integer
y, por lo tanto, no requerirá ningún boxeo / unboxing. Será mejor si los objetos se repiten una gran cantidad de veces.
En cuanto a cuál elegir, lo mejor es codificar para mayor claridad y optimizar cuando sea necesario. Para mí, groupingBy(x->x, counting())
expresa la intención más claramente, así que esa es la que preferiría.
Quiero contar los diferentes elementos de una secuencia y me pregunto por qué
Stream<String> stream = Stream.of("a", "b", "a", "c", "c", "a", "a", "d");
Map<String, Integer> counter1 = stream.collect(Collectors.toMap(s -> s, 1, Integer::sum));
no funciona Eclipse me dice
El método paraMapa (Función, Función, Operador Binario) en el tipo Colectores no es aplicable para los argumentos (s) -> {}, int, Entero :: suma)
Por cierto, sé acerca de esa solución:
Map<String, Long> counter2 = stream.collect(Collectors.groupingBy(s -> s, Collectors.counting()));
Entonces tengo dos preguntas:
- ¿Cuál es el error en mi primer acercamiento?
- ¿Cómo implementarías tal contador?
EDIT: resolví la primera pregunta por mi cuenta:
Map<String, Integer> counter1 = stream.collect(Collectors.toMap(s -> s, s -> 1, Integer::sum));
Java espera una función como segundo argumento.