我有一堂课叫做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")));

现在,我想基于以下内容合并这些:
  • 如果map2包含map1中不存在的键,只需将该键与map1中的值一起添加
  • 如果map2包含map1中存在的密钥,请检查map1中的Person是否存在相同的ID,如果是,请更新此person,如果没有不存在具有相同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);
    

    最佳答案

    您可能希望在那里进行一些抽象以提高可读性:

    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;
    }
    

    07-24 09:38
    查看更多