Java Lambda - Trying to sum by 2 groups

Estevao Santiago :

I have a object list, which I need to group by 2 different atributes and then sum the values of an attribute, the structure of my object is something like this:

private Long id1;
private Long id2;
private Double amountReserved;
private Double amountRequired;
//... more atributes and getters and setters

So, I then have a list, for example:

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));

What I am trying to achieve is a new list with the below structure:

list(1, A, 100, 100) 
list(1, B,   0, 100)
list(2, A,  15,   0)
list(3, A,   0,  25)

Elucidating what is the requisite I am trying to achieve:

  1. Group objects by id1 and id2
  2. sum the amountReservedof the grouped object
  3. subtract amountRequired from the summed amountReserved

What I have so far:

This one got me the groupings as I wanted

Map<Long, Map<String, List<MyList>>> map = null;
map = lista.stream().collect(Collectors.groupingBy(PreSeparacaoDto::getCodigoPedido,
                    Collectors.groupingBy(PreSeparacaoDto::getCodigoProduto)));

This one sums by group id1, but I am struggling to add the second groupingby on it, as I get syntax errors:

lista.stream()
        .collect(Collectors.groupingBy(PreSeparacaoDto::getCodigoPedido,
                Collectors.summingDouble(PreSeparacaoDto::getProdutoQuantidadeSeparada)))
        .forEach((codigoPedido, ProdutoQuantidadeSeparada) -> System.out.println( codigoPedido + ": " + ProdutoQuantidadeSeparada  ));

My problem is that I failed to get those together ( as per requisite 2) and was not even close to achieve my requisite 3.

I tried to use reduction, as explained here , but honestly, I was not able to replicate it with a single grouping, the reducing is returning an error informing that my parameters don't meet the reducing parameters. I looked for some other options here on stackoverflow and other websites, but without success.

Can someone help me out and poiting where I am failing to combine the reduction with my group, or if that is the correct path I should be following.

Naman :

You might just be looking for simply Collectors.toMap as :

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());

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=78623&siteId=1