Nesta resposta, estou mostrando o que acontece se você repetir A
elementos em sua List<A> listofA
lista.
Na verdade, se houvesse duplicatas listofA
, o código a seguir geraria um IllegalStateException
:
Map<A, Collection<B>> resultMap = listofA.stream()
.collect(Collectors.toMap(
Function.identity(),
repo::getListofB);
A exceção pode ser lançada porque Collectors.toMap
não sabe como mesclar valores quando há uma colisão nas chaves (ou seja, quando a função do mapeador de chaves retorna duplicatas, como seria o caso Function.identity()
se houvesse elementos repetidos na listofA
lista).
Isso é claramente afirmado nos documentos :
Se as chaves mapeadas contiverem duplicatas (de acordo com Object.equals(Object)
), um IllegalStateException
será lançado quando a operação de coleta for executada. Se as chaves mapeadas podem ter duplicatas, use toMap(Function, Function, BinaryOperator
).
Os documentos também nos fornecem a solução: caso haja elementos repetidos, precisamos fornecer uma maneira de mesclar valores. Aqui está uma dessas maneiras:
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;
});
Isso usa a versão sobrecarregada Collectors.toMap
que aceita uma função de mesclagem como seu terceiro argumento. Dentro da função de mesclagem, Collection.addAll
está sendo usado para adicionar os B
elementos de cada A
elemento repetido em uma lista unqiue para cada um A
.
Na função do mapeador de valores, um novo ArrayList
é criado, para que o original List<B>
de cada A
um não seja alterado. Além disso, ao criar um Arraylist
, sabemos com antecedência que ele pode ser alterado (ou seja, podemos adicionar elementos a ele posteriormente, caso haja duplicatas listofA
).
A
elementos repetidos no seuList<A>
?