【问题标题】:Merge two maps in Group by合并 Group by 中的两个地图
【发布时间】:2021-02-05 10:36:42
【问题描述】:

我有物品清单,

class Item {
    int id;
    String name;
    Map<String, String> map;
}

Item item1 = new Item(11, "name1", Map.of("k1", "v1"));
Item item2 = new Item(11, "name1", Map.of("k2", "v2"));
Item item3 = new Item(22, "name2", Map.of("k3", "v3"));
.
.
.

List<Item> list = List.of(item1, item2, item3 ...);

我想按 id 分组,但地图值保留了不同的值,如下所示,

List<Item> output = [ 11, "name1", map: { ["k1", "v1"],["k2", "v2"])) ], [ 22, "name2", map: { ["k3", "v3"] ] .....;

我尝试使用 group by 并返回,我如何在其中保留地图?

 Map<Integer, List<Item>> collect = list.stream()
              .collect(Collectors.groupingBy(Item::getId, Collectors.toList()));

【问题讨论】:

    标签: java java-stream


    【解决方案1】:

    您可以从一个列表中收集三个嵌套映射的结构,如下所示:

    List<Item> list = List.of(
            new Item(11, "name1", Map.of("k1", "v1")),
            new Item(11, "name1", Map.of("k2", "v2")),
            new Item(22, "name2", Map.of("k3", "v3")));
    
    Map<Integer, Map<String, Map<String, String>>> collect = list.stream()
            .collect(Collectors.groupingBy(
                    Item::getId,
                    Collectors.toMap(
                            Item::getName,
                            e -> new HashMap<>(e.getMap()),
                            (e1, e2) -> {
                                e1.putAll(e2);
                                return e1;
                            })));
    
    System.out.println(collect);
    // {22={name2={k3=v3}}, 11={name1={k1=v1, k2=v2}}}
    

    另见:How to split a string into a map, grouping values by duplicate keys using streams?

    【讨论】:

      【解决方案2】:

      要解决您的问题,您需要遍历这些值,并创建一个将所有地图分组为一个的新项目:

      List<Item> response = list.stream()
              .collect(Collectors.groupingBy(
                      Item::getId, Collectors.toList()))
              .values().stream()
              .map(v -> {
                  Item item = v.get(0);
                  Map<String, String> map = v.stream()
                          .flatMap(e -> e.getMap().entrySet().stream())
                          .collect(Collectors.toMap(
                                  Map.Entry::getKey,
                                  Map.Entry::getValue,
                                  (a, b) -> a));
                  return new Item(item.getId(), item.getName(), map);
              }).collect(Collectors.toList());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-03
        • 2019-07-29
        • 1970-01-01
        • 2012-02-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多