简体   繁体   English

在 Java 中合并两个集合

[英]Merge two collections in Java

I have two maps:我有两张地图:

Map<String, Student> students1 = new HashMap<>();
students1.put("New York", new Student("John"));
students1.put("Canada", new Student("Robert"));

Map<String, Student> students2 = new HashMap<>();
students2.put("Chicago", new Student("Nick"));
students2.put("New York", new Student("Ann"));

As a result, I want to get this:结果,我想得到这个:

{Canada=Robert, New York=[John, Ann], Chicago=Nick}

I can easily do it like this:我可以轻松地这样做:

Map<City, List<Student>> allStudents = new HashMap<>();

students1.forEach((currentCity, currentStudent) -> {
    allStudents.computeIfPresent(currentCity, (city, studentsInCity) -> {
        studentsInCity.add(currentStudent);
        return studentsInCity;
    });

    allStudents.putIfAbsent(currentCity, new ArrayList<Student>() {
        {
            add(currentStudent);
        }
    });
});

// then again for the second list

But is there any other way to merge many collections (two in this case)?但是有没有其他方法可以合并许多集合(在这种情况下是两个)? Is there something like short lambda expression, or method from some of the integrated java libraries, etc...?是否有类似简短的 lambda 表达式,或来自某些集成 Java 库的方法等...?

You could create a stream over any number of maps, then flat map over their entries.您可以在任意数量的地图上创建一个流,然后在它们的条目上创建平面地图。 It is then as simple as grouping by the key of the entry, with the value of the entry mapped to a List as value:然后就像按条目的键分组一样简单,将条目的值映射到List作为值:

Map<String, List<Student>> collect = Stream.of(students1, students2)
    .flatMap(map -> map.entrySet().stream())
    .collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

With static import for readability:使用静态导入以提高可读性:

Map<String, List<Student>> collect = Stream.of(students1, students2)
    .flatMap(map -> map.entrySet().stream())
    .collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toList())));

Replace toList() with toSet() if a Set is more appropriate as value of the map.替换toList()toSet()如果一个Set是作为地图的值比较合适。

I think the Stream version given by Magnilex is the most elegant way to do this.我认为 Magilex 提供的Stream版本是最优雅的方式。 But I still want to give another choice.但我还是想再给一个选择。

static final Function<...> NEW_LIST = __ -> new ArrayList<>();

Map<City, List<Student>> allStudents = new HashMap<>();

students1.forEach((city, student) -> {
    allStudents.computeIfAbsent(city, NEW_LIST).add(student);
});

https://www.baeldung.com/java-merge-maps这是一个链接,应该会有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM