【问题标题】:Group and sum data from a list of objects while preserving the insertion order对对象列表中的数据进行分组和求和,同时保留插入顺序
【发布时间】:2021-02-26 05:17:24
【问题描述】:

我有一个DijkstraWays 对象列表:

List<DijkstraWays> dijkstraWaysList= ...

DijkstraWays 具有以下属性和 getter:

class DijkstraWays {
    String name;
    Double cost;

    public String getName() {
        return name;
    }

    public Double getCost() {
        return cost;
    }
}

我需要按name 对这个列表进行分组,并得出cost 的总和。为此,我使用了以下代码:

Map<String, Double> result = dijkstraWaysList.stream()              
             .collect(Collectors.groupingBy(DijkstraWays::getName, 
                      Collectors.summingDouble(DijkstraWays::getCost)));

此代码有效,但它不保留djkstraWaysList 列表中元素的插入顺序。这是因为Collectors.groupingBy返回的是一个Map/HashMap,而这种类型不保留插入顺序。

如何使用Collectors.groupingByCollectors.summingDouble 保留djkstraWaysList 列表的插入顺序?我在互联网上找到了几个示例,其中结果被转换为LinkedHashMap,它保留了这一点,但没有一个可以插入Collectors.summingDouble。示例:

dijkstraWays.stream()
            .collect(Collectors.groupingBy(DijkstraWays::getName,
                                LinkedHashMap::new,
                                Collectors.toList()));

我还需要 cost 的总和,但在这些带有 LinkedHashMap 的示例中,我不能将它与 groupby 一起使用。

谢谢。

【问题讨论】:

  • 你的意思是Collectors.groupingBy(DijkstraWays::getName, LinkedHashMap::new, Collectors.summingDouble(DijkstraWays::getCost))
  • 谢谢@ernest_k。这非常有效。代码:LinkedHashMap collect = dijkstraWays.stream() .collect(Collectors.groupingBy(DijkstraWays::getName, LinkedHashMap::new, Collectors.summingDouble(DijkstraWays::getCost)));

标签: java collections java-stream


【解决方案1】:

LinkedHashMapSupplier&lt;Map&gt; 应插入到Collectors.groupingBy 中的下游收集器(在本例中为Collectors.summingDouble)之前:

public static Map<String, Double> totalCostGroupByName(List<DijkstraWays> ways) {
    return ways.stream()              
            .collect(Collectors.groupingBy(DijkstraWays::getName,
                    LinkedHashMap::new,
                    Collectors.summingDouble(DijkstraWays::getCost)
            ));
}

测试:

List<DijkstraWays> ways = Arrays.asList(
    new DijkstraWays("AB", 3),
    new DijkstraWays("AC", 5),
    new DijkstraWays("AD", 4),
    new DijkstraWays("BC", 3),
    new DijkstraWays("AC", 2),
    new DijkstraWays("AB", 6),
    new DijkstraWays("CD", 10)
);

System.out.println(totalCostGroupByName(ways)); // {AB=9.0, AC=7.0, AD=4.0, BC=3.0, CD=10.0}

【讨论】:

  • 谢谢亚历克斯。这段代码运行良好,正是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
  • 2020-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
相关资源
最近更新 更多