Tengo una lista de tipos List<A>y con la operación de mapa obtengo una lista colectiva de tipos List<B>para todos los elementos A fusionados en una lista.
List<A> listofA = [A1, A2, A3, A4, A5, ...]
List<B> listofB = listofA.stream()
.map(a -> repo.getListofB(a))
.flatMap(Collection::stream)
.collect(Collectors.toList());
sin plano
List<List<B>> listOflistofB = listofA.stream()
.map(a -> repo.getListofB(a))
.collect(Collectors.toList());
Quiero recopilar los resultados como un mapa de tipo Map<A, List<B>>y hasta ahora intentar con varias opciones Collectors.toMapu Collectors.groupingByopciones, pero no puedo obtener el resultado deseado.
java
lambda
java-8
java-stream
collectors
Amitoj
fuente
fuente

Aelementos repetidos en tuList<A>?Respuestas:
Puede usar el
toMaprecopilador con una referencia de método acotado para obtener lo que necesita. Observe también que esta solución asume que no tiene instancias A repetidas en su contenedor fuente. Si esa precondición mantiene esta solución, obtendría el resultado deseado. Así es como se ve.Si tiene elementos A duplicados, debe usar esta función de combinación además de lo que se proporciona anteriormente. La función de fusión se ocupa de conflictos clave, si los hay.
Y aquí hay un enfoque Java9 mucho más sucinto que utiliza el
flatMappingrecopilador para manejar elementos A repetidos.fuente
Sería sencillo
fuente
Para recopilar un
Mapdonde las claves son losAobjetos sin cambios, y los valores son la lista deBobjetos correspondientes , puede reemplazar eltoList()recopilador por el siguiente recopilador:El primer argumento define cómo calcular la clave del objeto original:
identity()toma el objeto original de la secuencia sin cambios.El segundo argumento define cómo se calcula el valor , por lo que aquí solo consiste en una llamada a su método que transforma
Aa una lista deB.Dado que el
repométodo solo toma un parámetro, también puede mejorar la claridad reemplazando el lambda con una referencia de método:fuente
En esta respuesta, estoy mostrando lo que sucede si tienes
Aelementos repetidos en tuList<A> listofAlista.En realidad, si hubiera duplicados
listofA, el siguiente código arrojaría unIllegalStateException:La excepción podría ser lanzada porque
Collectors.toMapno 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 casoFunction.identity()si hubiera elementos repetidos en lalistofAlista).Esto se afirma claramente en los documentos :
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:
Esto usa la versión sobrecargada
Collectors.toMapque acepta una función de fusión como su tercer argumento. Dentro de la función de fusión,Collection.addAllse está utilizando para agregar losBelementos de cadaAelemento repetido en una lista única para cada unoA.En la función del mapeador de valores,
ArrayListse crea un nuevo , de modo que el originalList<B>de cada unoAno está mutado. Además, como estamos creando unArraylist, sabemos de antemano que puede ser mutado (es decir, podemos agregarle elementos más adelante, en caso de que haya duplicadoslistofA).fuente