Обратная группировка в java 8

Я могу сгруппировать список студентов, используя приведенное ниже лямбда-выражение. В результате список студентов будет сгруппирован по «Отделу», а затем по «полу».

Map<String, Map<String, List<Student>>> studentCatg = studentList.stream().collect(groupingBy(Student::getDepartment, groupingBy(Student::getGender)));

Теперь мне нужно получить единый список из приведенной выше карты, который должен содержать студентов определенного факультета. Есть ли что-нибудь обратное группировке?


person june    schedule 17.08.2017    source источник


Ответы (2)


Вы можете получить EntrySet для данного отдела, объединить Map<String, List<Student>> с List<List<Student>> с помощью map для ввода заданного значения, а затем flatMap с List<Student>, примерно так:

String department = "department name";
List<Student> students = studentCatg.get(department)
    .values()
    .stream()
    .flatMap(Collection::stream)
    .collect(Collectors.toList())

Возврат к первоначальному списку

List<Student> students = studentCatg.values()
        .stream()
        .map(Map::values)
        .flatMap(Collection::stream)
        .flatMap(Collection::stream)
        .collect(Collectors.toList());
person Szymon Stepniak    schedule 17.08.2017
comment
Только что отредактировал ваш пост и получил ответ. Спасибо, кстати. Отдел String = название отдела; Список‹Студент› студентов = studentCatg.get(department).values.stream().flatMap(Collection::stream).collect(Collectors.toList()) - person june; 17.08.2017
comment
@june Да, это можно упростить, взяв values вместо entrySet, хороший улов! :) - person Szymon Stepniak; 17.08.2017
comment
есть код для полного реверса? Список в Map‹String, Map‹String, список›› по группировке. Теперь Map‹String, Map‹String, list›› в список? - person june; 17.08.2017
comment
@june Вы имеете в виду обратный исходный список studentList? - person Szymon Stepniak; 17.08.2017
comment
@june Я обновил ответ, чтобы объяснить и этот случай. - person Szymon Stepniak; 17.08.2017
comment
Идеально .. Я пробовал несколько, но не . позвольте мне еще немного покопаться в потоках. Спасибо. - person june; 18.08.2017

Я нашел эту запись, когда искал способ инвертировать карту groupingBy, но, поскольку я не нашел общего решения, я построил свое собственное, так что на случай, если оно представляет интерес.

public static <K, V> Map<V, List<K>> invertGroupByMap(final Map<K, List<V>> src)
{
    return src.entrySet().stream()
            .flatMap(e -> e.getValue().stream().map(a -> new SimpleImmutableEntry<>(a, e.getKey())))
            .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
}
person JustifiedAndAncient    schedule 05.02.2018