Tengo una lista de objetos, lo que necesito para agrupar por 2 atributos diferentes y luego sumar los valores de un atributo, la estructura de mi objeto es algo como esto:
private Long id1;
private Long id2;
private Double amountReserved;
private Double amountRequired;
//... more atributes and getters and setters
Por lo tanto, a continuación, tengo una lista, por ejemplo:
List<MyList> list = Arrays.asList(
list(1, A, 50, 200)
list(1, A, 50, 200)
list(1, B, 0, 100)
list(2, A, 10, 15)
list(2, A, 5, 15)
list(3, A, 0, 25));
Lo que estoy tratando de lograr es una nueva lista con la siguiente estructura:
list(1, A, 100, 100)
list(1, B, 0, 100)
list(2, A, 15, 0)
list(3, A, 0, 25)
La aclaración de lo que es el requisito que estoy tratando de lograr:
- Grupo de objetos por ID1 e ID2
- sumar la
amountReserved
del objeto agrupado - restar
amountRequired
de la resumióamountReserved
Lo que tengo hasta ahora:
Este me consiguió las agrupaciones como quería
Map<Long, Map<String, List<MyList>>> map = null;
map = lista.stream().collect(Collectors.groupingBy(PreSeparacaoDto::getCodigoPedido,
Collectors.groupingBy(PreSeparacaoDto::getCodigoProduto)));
Éste sumas por ID1 grupo, pero estoy luchando para añadir el segundo groupingby en él, como consigo errores de sintaxis:
lista.stream()
.collect(Collectors.groupingBy(PreSeparacaoDto::getCodigoPedido,
Collectors.summingDouble(PreSeparacaoDto::getProdutoQuantidadeSeparada)))
.forEach((codigoPedido, ProdutoQuantidadeSeparada) -> System.out.println( codigoPedido + ": " + ProdutoQuantidadeSeparada ));
Mi problema es que no pude conseguir esos juntas (como por requisito 2) y no estaba ni siquiera cerca de lograr mi requisito 3.
He intentado utilizar la reducción, como se ha explicado aquí , pero sinceramente, yo no era capaz de replicar con una sola agrupación, la reducción se devolverá un error informándole de que mis parámetros no cumplen con los reducing
parámetros. Busqué algunas otras opciones aquí en StackOverflow y otros sitios web, pero sin éxito.
Alguien me puede ayudar a cabo y poiting donde estoy fallando para combinar la reducción con mi grupo, o si ese es el camino correcto que debería estar siguiendo.
Es posible que sólo se busca simplemente Collectors.toMap
como:
List<MyList> output = new ArrayList<>(lista.stream()
.collect(Collectors.toMap(a -> a.getId1() + "-" + a.getId2(), a -> a, (myList1, myList2) -> {
myList1.amountReserved = myList1.amountReserved + myList2.amountReserved;
myList1.amountRequired = myList1.amountRequired - myList1.amountReserved;
return myList1;
})).values());