Объединить две коллекции в Java - PullRequest
0 голосов
/ 23 февраля 2020

У меня есть две карты:

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

В результате я хочу получить это:

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

Я могу легко сделать это так:

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

Но есть ли другой способ объединить множество коллекций (в данном случае две)? Есть ли что-то вроде короткого лямбда-выражения или метода из некоторых интегрированных библиотек java, et c ...?

Ответы [ 3 ]

3 голосов
/ 23 февраля 2020

Вы можете создать поток по любому количеству карт, а затем распланировать их записи. Тогда это так же просто, как группировка по ключу записи, со значением записи, сопоставленным с 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())));

С stati c импорт для удобства чтения:

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

Заменить toList() на toSet(), если Set больше подходит в качестве значения карты.

0 голосов
/ 23 февраля 2020

https://www.baeldung.com/java-merge-maps это ссылка, она должна помочь

0 голосов
/ 23 февраля 2020

Я думаю, что версия Stream от Magnilex - самый элегантный способ сделать это. Но я все еще хочу дать другой выбор.

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);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...