【问题标题】:Summing values of an object by first filtering other unique values of the same object通过首先过滤同一对象的其他唯一值来对对象的值求和
【发布时间】:2019-05-31 20:38:08
【问题描述】:

假设我有一个对象列表,让我们调用这个对象 Order,它有一个数量和价格作为字段。

例如如下:

对象Order(字段quantityprice)列表包含以下值:

Quantity  Price

5         200
6         100
3         200
1         300

现在我想使用 Java-8 来获取按以下方式过滤的列表:

Quantity  Price

8         200
6         100
1         300

Price 是要从中过滤的唯一值,并对价格的任何数量求和,我想在此基础上形成一个新列表。

请建议我如何使用 java 8 lambda 表达式做到这一点,谢谢。

【问题讨论】:

  • 你也应该提供你的尝试:)
  • 我的尝试太尴尬了,不能在这里展示 lol @Nikolas
  • 从不尴尬!它可以帮助我们提供更好的答案,为您提供反馈并帮助您修复当前的解决方案。继续并发布它。 :)
  • 啊,我找到你了。试试这个:List<Order> buyOrdersSummed = orders.stream().collect(Collectors.collectingAndThen(Collectors.groupingBy(Order::getPrice), map -> map.entrySet().stream().map(e -> new Order(e.getKey(), e.getValue().get(0).getUserId(), e.getValue().stream().mapToInt(i -> i.getQuantity()).sum())).collect(Collectors.toList())));。分组将使用相同的键进行,但不是summingInt,而是让生成List<Order>. Then in the finisher`,您使用这些命令来计算userId(我假设第一个)和quantity作为总和并传递它全部到一个新对象。
  • @Nikolas 哇,谢谢。多亏了你,我今天学到了很多东西:)

标签: java list arraylist java-8 java-stream


【解决方案1】:

以下Stream 可以解决问题:

List<Order> o  = orders.stream().collect(
    Collectors.collectingAndThen(
        Collectors.groupingBy(Order::getPrice,Collectors.summingInt(Order::getQuantity)),
        map -> map.entrySet().stream()
                             .map(e -> new Order(e.getKey(), e.getValue()))
                             .collect(Collectors.toList())));

让我们分解一下:

  1. 以下代码返回一个Map&lt;Integer, Integer&gt;,其中包含作为键的价格(您要作为求和基础的唯一值)及其总和数量。关键方法是Collectors.groupingBy,其中classifier 描述关键,downstream 定义一个值,这将是数量的总和,因此Collectors.summingInt(取决于quantity 类型):

    Map<Integer, Integer> map = orders.stream().collect(
        Collectors.groupingBy(                            // I want a Map<Integer, Integer>
            Order::getPrice,                              // price is the key
            Collectors.summingInt(Order::getQuantity))    // sum of quantities is the value
    
  2. 所需的结构是List&lt;Order&gt;,因此您希望将Collectors.collectingAndThen 方法与Collector&lt;T, A, R&gt; downstreamFunction&lt;R, RR&gt; finisher 结合使用。 downstream 是从第一点开始的分组,完成者将Map&lt;Integer, Integer&gt; 转换回List&lt;Order&gt;

    List<Order> o  = orders.stream().collect(
    Collectors.collectingAndThen(
        grouping,                                                 // you know this one ;)
        map -> map.entrySet()                        
                  .stream()                                       // iterate entries
                  .map(e -> new Order(e.getKey(), e.getValue()))  // new Order(qty, price)
                  .collect(Collectors.toList())));                // as a List<Order>
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 2021-01-16
    • 2022-09-27
    • 2020-10-14
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多