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

问题描述

似乎我不太了解 groupingBy & 收集器 & 排序的概念。

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

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

类产品:

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

上课顺序:

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

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

主类

       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 方法或更简单的方法(例如 max)通过 Value 对地图进行排序?

标签: javasortingstreamjava-streamgroupingby

解决方案


您正在使用reduce接受 a的一个参数版本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())));

推荐阅读