Java 8 stream.collect (... groupingBy (... mapping (... reduce))) reduciendo el uso de BinaryOperator
Jugué con una solución usandogroupingBy
, mapping
yreducing
a la siguiente pregunta:Cree elegantemente un mapa con campos de objetos como clave / valor de la secuencia de objetos en Java 8. Resumió que el objetivo era obtener un mapa con la edad como clave y los pasatiempos de una persona comoSet
.
Una de las soluciones que se me ocurrió (no es agradable, pero ese no es el punto) tenía un comportamiento extraño.
Con la siguiente lista como entrada:
List<Person> personList = Arrays.asList(
new Person(/* name */ "A", /* age */ 23, /* hobbies */ asList("a")),
new Person("BC", 24, asList("b", "c")),
new Person("D", 23, asList("d")),
new Person("E", 23, asList("e"))
);
y la siguiente solución:
Collector<List<String>, ?, Set<String>> listToSetReducer = Collectors.reducing(new HashSet<>(), HashSet::new, (strings, strings2) -> {
strings.addAll(strings2);
return strings;
});
Map<Integer, Set<String>> map = personList.stream()
.collect(Collectors.groupingBy(o -> o.age,
Collectors.mapping(o -> o.hobbies, listToSetReducer)));
System.out.println("map = " + map);
Tengo:
map = {23=[a, b, c, d, e], 24=[a, b, c, d, e]}
claramente no era lo que esperaba. Prefiero esto:
map = {23=[a, d, e], 24=[b, c]}
Ahora si solo reemplazo el orden de(strings, strings2)
del operador binario (del colector reductor) a(strings2, strings)
Obtengo el resultado esperado. Entonces, ¿qué extrañé aquí? ¿Interpreté mal elreducing
-¿coleccionista? ¿O qué parte de la documentación me perdí que hace obvio que mi uso no estaba funcionando como se esperaba?
La versión de Java es 1.8.0_121 si eso importa.