I have a list of objects of class Result
defined as:
class Result {
String code;
String description;
Duration value;
}
and these two classes:
class Product {
String code;
String description;
}
class Total {
Duration total;
long count;
}
Given the List<Result>
I have to generate a Map<Product, Total>
where in total I have the sum of every value in Result
that has the same code
and description
(this is key) and as count how many result with this key is present in the list of results.
For creating the total sum I consider to use plus(Duration)
of Duration
.
How can I do this?
Thanks for the help.
From the comments hints I was able to do this:
(Can someone tell me if it can be correct?)
Map <Product, Total> map = results.stream()
.collect(Collectors.groupingBy(p -> new Product(p.getCode(), p.getDescription()),
Collectors.collectingAndThen(Collectors.toList(), list -> {
Duration total = list.stream().map(Result::getValue).reduce(Duration.ZERO, Duration::plus);
long count = list.size();
return new Total(total, count);
})));
Your approach is working and formally correct, but it is wasteful to collect all elements into List
s, just to perform another Reduction afterwards. Perform the Reduction in the first place:
Map<Product, Total> map = results.stream()
.collect(Collectors.groupingBy(r -> new Product(r.getCode(), r.getDescription()),
Collectors.teeing(
Collectors.reducing(Duration.ZERO, Result::getValue, Duration::plus),
Collectors.counting(),
Total::new)));