【问题标题】:Merge Map based on a condition根据条件合并地图
【发布时间】:2020-03-05 03:05:51
【问题描述】:

我有一个名为 Person 的类:

class Person {
    private String id;
    private String name;
}

现在我有两张地图

final Map<Integer, List<Person>> map1 = ImmutableMap.of(1, ImmutableList.of(
                new Person("id1", "name1"),
                new Person("id2", "name2")),
                2, ImmutableList.of(
                        new Person("id3", "name3"),
                        new Person("id4", "name4")));

final Map<Integer, List<Person>> map2 = ImmutableMap.of(2, ImmutableList.of(
                    new Person("id1", "name5")));

现在我想根据以下合并这些:

  1. 如果 map2 包含 map1 中不存在的键,只需将该键与 map1 中的值一起添加
  2. 如果 map2 包含 map1 中存在的键,检查 map1 中是否存在具有相同 id 的人,如果是,则更新该人,如果不存在具有相同 id 的人,只需将新人添加到列表。

上述情况的结果是

1 -> Person("id1", "name5"), Person("id2", "name2")
2 -> Person("id3", "name3"), Person("id4", "name4")

我可以使用原始方式来完成它,但是它很大,我正在尝试为此提出一个干净的基于 Java 8 流的解决方案。

任何帮助将不胜感激。

final HashMap<Integer, List<Person>> map1 = new HashMap<Integer, List<Person>>() {{
    put(1, Arrays.asList(
            new Person("id1", "name1"),
            new Person("id2", "name2")));
    put(2, Arrays.asList(
            new Person("id3", "name3"),
            new Person("id4", "name4")));
}};

final HashMap<Integer, List<Person>> map2 = new HashMap<Integer, List<Person>>() {{
    put(1, Arrays.asList(
            new Person("id1", "name5")));
}};

final Map<Integer, List<Person>> collect = Stream.of(map1, map2).flatMap(map -> map.entrySet().stream())
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                Map.Entry::getValue, (v1, v2) -> {
                    List<Person> h = new ArrayList<>();
                    h.addAll(v1);
                    v2.forEach(x -> {
                        v1.forEach(y -> {
                            if(x.getId().equals(y.getId())) {
                                h.remove(y);
                            }
                        });
                    });
                    h.addAll(v2);
                    return h;
                }
        ));

System.out.println(collect);

【问题讨论】:

    标签: java java-8 java-stream


    【解决方案1】:

    您可能需要一些抽象以提高可读性:

    Map<Integer, List<Person>> collect =
            Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
                    .collect(Collectors.toMap(Map.Entry::getKey,
                            Map.Entry::getValue, this::mergeFunc));
    
    public List<Person> mergeFunc(List<Person> peopleOne, List<Person> peopleTwo) {
        List<Person> mergedPeople = new ArrayList<>(peopleOne);
        mergedPeople.removeIf(y -> peopleTwo.stream().anyMatch(p -> y.getId().equals(p.getId())));
        mergedPeople.addAll(peopleTwo);
        return mergedPeople;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 1970-01-01
      相关资源
      最近更新 更多