对对象列表中的数据进行分组和求和,同时保留插入顺序

Group and sum data from a list of objects while preserving the insertion order

我有一个 DijkstraWays 个对象的列表:

List<DijkstraWays> dijkstraWaysList= ...

DijkstraWays 具有以下属性和吸气剂:

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 returns 一个 Map / HashMap,并且这种类型不保留插入顺序。

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

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

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

谢谢。

Supplier<Map> for LinkedHashMap 应该插入到 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}