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

huangapple go评论80阅读模式
英文:

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

问题

以下是翻译好的内容:

似乎我不太理解 groupingBy 和 collectors 以及 sorting 的概念。

任务:使用 Streams 求订单数量按类别分组的总和。然后获取具有最大数量的类别,并将其作为单行映射行打印在图片上,显示顶部值。

3 个类(2 个记录:Product 和 Order + Main)。在 Main 中有一个新订单的 List。

Product 类:

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

Order 类:

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

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

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

以下是我关于分组的实现:

    Map<String, Integer> summedQuantitiesPerCategory = orders //编号 1。
        .stream()
        .collect(Collectors.groupingBy(p -> p.product().category(),
            Collectors.summingInt(p -> p.quantity())
        ));

    summedQuantitiesPerCategory.entrySet()
        .stream()
        .sorted(Map.Entry.comparingByValue()) // 编号 2。
        .limit(1);

问题:
1. 如何摆脱 Optional,并在映射中只看到 Integer 作为值。然后排序应该很容易吧。
2. 如何通过值对映射进行排序,使用 Sorted 方法或者更简单的方法,比如 max?
英文:

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&lt;Order&gt; orders = List.of(
            new Order(new Product(&quot;chleb&quot;, new BigDecimal(5), &quot;A&quot;),10, new BigDecimal(&quot;0.1&quot;)),
            new Order(new Product(&quot;maslo&quot;, new BigDecimal(6), &quot;A&quot;),5, new BigDecimal(&quot;0.2&quot;)),
            new Order(new Product(&quot;szynka&quot;, new BigDecimal(25), &quot;B&quot;),10, new BigDecimal(&quot;0&quot;)),
            new Order(new Product(&quot;kielbasa&quot;, new BigDecimal(16),&quot;C&quot;),5, new BigDecimal(&quot;0&quot;)),
            new Order(new Product(&quot;woda&quot;, new BigDecimal(3),&quot;B&quot;),15, new BigDecimal(&quot;0.1&quot;)),
            new Order(new Product(&quot;ocet&quot;, new BigDecimal(3),&quot;A&quot;),8, new BigDecimal(&quot;0.3&quot;)),
            new Order(new Product(&quot;margaryna&quot;, new BigDecimal(4),&quot;B&quot;),12, new BigDecimal(&quot;0.5&quot;)),
            new Order(new Product(&quot;maslo&quot;, new BigDecimal(8),&quot;C&quot;),5, new BigDecimal(&quot;0.2&quot;))
            )

Below my implementation of grouping:

        Map&lt;String, Optional&lt;Integer&gt;&gt; summedQuantitiesPerCategory = orders //no 1.
            .stream()
            .collect(Collectors.groupingBy(p -&gt; p.product().category(),
                    Collectors.collectingAndThen(
                            Collectors.mapping(p -&gt; p.quantity(), Collectors.toList()),
                            quantity -&gt; quantity.stream().reduce((x, y) -&gt; x + y) 
                    )));


        summedQuantitiesPerCategory
            .entrySet()
            .stream()
            .sorted(Comparator.comparing(p -&gt; p.getValue())) // no2.
            .limit(1);

Questions:

  1. 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
  2. How to sort map via Value using method Sorted or something more simple like e.g. max?

答案1

得分: 1

你正在使用接受BinaryOperatorreduce的单参数版本。你可以传递一个身份值和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())));
英文:

You are using the one argument version of reduce which accepts a BinaryOperator. You can pass an identity value along with the BinaryOperator.

quantity -&gt; quantity.stream().reduce(0, (x, y) -&gt; x + y)

or

quantity -&gt; quantity.stream().reduce(0, Integer::sum)

Since you just want to sum the quantity, you can use Collectors.summingInt

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

huangapple
  • 本文由 发表于 2020年10月6日 23:15:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/64228754.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定