Seems like i do not quite understand the concepts of groupingBy & collectors & sorting.
Task: to sum the number of order's quantity grouped by Category using Streams. Then get category with Max quantity and print it out on the picture as single map row with top value
3 classes (2 Records: Product & Order + Main). In Main there is an List.of new orders
Class Product:
public record Product(String name, BigDecimal price, String category)
Class Order:
public record Order(Product product, int quantity, BigDecimal discount)
public BigDecimal priceWithDiscount(){
return product.price().multiply(BigDecimal.ONE.subtract(discount));
}
Class Main
List<Order> orders = List.of(
new Order(new Product("chleb", new BigDecimal(5), "A"),10, new BigDecimal("0.1")),
new Order(new Product("maslo", new BigDecimal(6), "A"),5, new BigDecimal("0.2")),
new Order(new Product("szynka", new BigDecimal(25), "B"),10, new BigDecimal("0")),
new Order(new Product("kielbasa", new BigDecimal(16),"C"),5, new BigDecimal("0")),
new Order(new Product("woda", new BigDecimal(3),"B"),15, new BigDecimal("0.1")),
new Order(new Product("ocet", new BigDecimal(3),"A"),8, new BigDecimal("0.3")),
new Order(new Product("margaryna", new BigDecimal(4),"B"),12, new BigDecimal("0.5")),
new Order(new Product("maslo", new BigDecimal(8),"C"),5, new BigDecimal("0.2"))
)
Below my implementation of grouping:
Map<String, Optional<Integer>> summedQuantitiesPerCategory = orders //no 1.
.stream()
.collect(Collectors.groupingBy(p -> p.product().category(),
Collectors.collectingAndThen(
Collectors.mapping(p -> p.quantity(), Collectors.toList()),
quantity -> quantity.stream().reduce((x, y) -> x + y)
)));
summedQuantitiesPerCategory
.entrySet()
.stream()
.sorted(Comparator.comparing(p -> p.getValue())) // no2.
.limit(1);
Questions:
- How to get rid of this Optional and see only Integer as a value in the map. Then it would be easy to sort i guess
- How to sort map via Value using method Sorted or something more simple like e.g. max?
You are using the one argument version of
reduce
which accepts aBinaryOperator
. You can pass an identity value along with theBinaryOperator
.or
Since you just want to sum the quantity, you can use
Collectors.summingInt