En esta respuesta, estoy mostrando lo que sucede si tienes A
elementos repetidos en tu List<A> listofA
lista.
En realidad, si hubiera duplicados listofA
, el siguiente código arrojaría un IllegalStateException
:
Map<A, Collection<B>> resultMap = listofA.stream()
.collect(Collectors.toMap(
Function.identity(),
repo::getListofB);
La excepción podría ser lanzada porque Collectors.toMap
no sabe cómo fusionar valores cuando hay una colisión en las teclas (es decir, cuando la función del mapeador de teclas devuelve duplicados, como sería el caso Function.identity()
si hubiera elementos repetidos en la listofA
lista).
Esto se afirma claramente en los documentos :
Si las claves asignadas contienen duplicados (de acuerdo con Object.equals(Object)
), IllegalStateException
se emite una cuando se realiza la operación de recopilación. Si las claves asignadas pueden tener duplicados, use toMap(Function, Function, BinaryOperator
) en su lugar.
Los documentos también nos dan la solución: en caso de que haya elementos repetidos, debemos proporcionar una forma de fusionar valores. Aquí hay una de esas formas:
Map<A, Collection<B>> resultMap = listofA.stream()
.collect(Collectors.toMap(
Function.identity(),
a -> new ArrayList<>(repo.getListofB(a)),
(left, right) -> {
left.addAll(right);
return left;
});
Esto usa la versión sobrecargada Collectors.toMap
que acepta una función de fusión como su tercer argumento. Dentro de la función de fusión, Collection.addAll
se está utilizando para agregar los B
elementos de cada A
elemento repetido en una lista única para cada uno A
.
En la función del mapeador de valores, ArrayList
se crea un nuevo , de modo que el original List<B>
de cada uno A
no está mutado. Además, como estamos creando un Arraylist
, sabemos de antemano que puede ser mutado (es decir, podemos agregarle elementos más adelante, en caso de que haya duplicados listofA
).
A
elementos repetidos en tuList<A>
?