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:
You are using the one argument version of reduce
which accepts a BinaryOperator
. You can pass an identity value along with the BinaryOperator
.
quantity -> quantity.stream().reduce(0, (x, y) -> x + y)
or
quantity -> quantity.stream().reduce(0, Integer::sum)
Since you just want to sum the quantity, you can use Collectors.summingInt
...
.collect(Collectors.groupingBy(p -> p.product().category(),
Collectors.summingInt(p -> p.quantity())));