Ich habe zwei Karten:

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"));

Als Ergebnis möchte ich Folgendes erhalten:

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

Ich kann es leicht so machen:

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

Aber gibt es eine andere Möglichkeit, viele Sammlungen zusammenzuführen (in diesem Fall zwei)? Gibt es so etwas wie einen kurzen Lambda-Ausdruck oder eine Methode aus einigen der integrierten Java-Bibliotheken usw.?

0
Kaloyan Velichkov 23 Feb. 2020 im 16:36

3 Antworten

Beste Antwort

Sie können einen Stream über eine beliebige Anzahl von Karten erstellen und dann eine flache Karte über deren Einträgen. Es ist dann so einfach wie das Gruppieren nach dem Schlüssel des Eintrags, wobei der Wert des Eintrags einem List als Wert zugeordnet wird:

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())));

Mit statischem Import zur besseren Lesbarkeit:

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

Ersetzen Sie toList() durch toSet(), wenn ein Set als Wert der Karte besser geeignet ist.

3
Magnilex 23 Feb. 2020 im 13:51

https://www.baeldung.com/java-merge-maps Dies ist eine Link, es sollte helfen

0
Buchi 23 Feb. 2020 im 14:41

Ich denke, die von Magnilex bereitgestellte Stream -Version ist der eleganteste Weg, dies zu tun. Aber ich möchte noch eine andere Wahl treffen.

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);
});
0
yyyy 23 Feb. 2020 im 14:05