Streams 中的 groupingBy 使用 CollectingAndThen 方法 -> 如何摆脱 Optional 然后在地图上使用 Max :)

groupingBy in Streams with CollectingAndThen method -> how to get rid of Optional then use Max on the map :)

好像不太明白groupingBy & collectors & sorting的概念

任务:使用 Streams 对按类别分组的订单数量求和。然后获取最大数量的类别并将其打印在图片上作为具有最高值的单个地图行

3 类(2 条记录:产品和订单 + 主要)。在 Main 有一个 List.of 新订单

Class 产品:

public record Product(String name, BigDecimal price, String category)

Class 订单:

public record Order(Product product, int quantity, BigDecimal discount)

public BigDecimal priceWithDiscount(){
    return product.price().multiply(BigDecimal.ONE.subtract(discount));
}

Class 主要

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

下面是我实现的分组:

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

问题:

  1. 如何摆脱这个 Optional 并在地图中仅将 Integer 视为值。我猜这样就很容易排序了
  2. 如何使用 Sorted 方法或更简单的方法通过 Value 对地图进行排序,例如最大?

您正在使用 reduce 的单参数版本,它接受 BinaryOperator。您可以将标识值与 BinaryOperator.

一起传递
quantity -> quantity.stream().reduce(0, (x, y) -> x + y)

quantity -> quantity.stream().reduce(0, Integer::sum)

因为你只是想求和数量,你可以使用Collectors.summingInt

...
.collect(Collectors.groupingBy(p -> p.product().category(),
                Collectors.summingInt(p -> p.quantity())));