-1

I have a list of:

public class Dto {
    private Integer id;
    private String text;
    private BigDecimal price;
}

I tried:

 Map<String, Map<Integer, List<Dto>>> map =
            list.stream()
                .collect(
                     Collectors.groupingBy(
                     Dto::getText,
                     Collectors.groupingBy(Dto::getId)));

but this did not give a sum of the BigDecimal field

Also I would like to have the return structure like:

List<SumDto>

public class SumDto {
      private Integer id;
      private String text;
      private BigDecimal sum;
}

How could I achieve this? Thank you very much

WJS
  • 36,363
  • 4
  • 24
  • 39
Aerondight
  • 33
  • 5

1 Answers1

1

You are not summing anything, that's why you don't see the sum anywhere. You have to tell Collectors.groupingBy how to reduce elements downstream. Otherwise, it creates a List by default.

This is how you could do it:

Map<String, Map<Integer, BigDecimal>> map = list.stream()
    .collect(Collectors.groupingBy(
             Dto::getText, 
             Collectors.groupingBy(
                        Dto::getId, 
                        Collectors.reducing(
                                   BigDecimal.ZERO,
                                   Dto::getPrice, 
                                   BigDecimal::add))));

As to the return structure, I will leave that as an exercise ;)

Woodchuck
  • 3,869
  • 2
  • 39
  • 70
fps
  • 33,623
  • 8
  • 55
  • 110
  • I would have thought the final value of the nested map would have been a single instance of `SumDto` (clearly not a list of anything) even though it contains redundant information. – WJS Dec 01 '20 at 16:01