Карта списка и карта в карту - PullRequest
3 голосов
/ 30 марта 2020
@Getter 
static class Student {
    private Map<Status, Marks> statusAndMarks; 
}

class Status {
}

class Marks {
}

Map<Status, Student> map = new HashMap<>();
for (Student student : studentList) {
    for (Status status : student.getStatusAndMarks().keySet()) {
        map.put(status, student);
    }
}

Как написать приведенный выше код в функциональном стиле в Java 8? Я написал следующий код, но как мне написать, что результатом моего кода является неизменяемая карта, и мне не нужно создавать карту до лямбды?

studentList
    .forEach(student -> {
        student
        .getStatusAndMarks()
        .keySet().stream()
        .map(key -> map.put(key, statusKeyImportantMessage));
        });

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Вы были достаточно близки, если бы использовали forEach для повторения набора ключей снова как:

Map<Status, Student> map = new HashMap<>();
studentList.forEach(student -> 
        student.getStatusAndMarks().keySet()
                .forEach(k -> map.put(k,student)));

Представление, аналогичное указанному в другом ответе, будет

Map<Status, Student> map = studentList.stream()
        .flatMap(s -> s.getStatusAndMarks().keySet()
                .stream()
                .map(status -> new AbstractMap.SimpleEntry<>(status, s)))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> b));

Обратите внимание, функция слияния предназначена для перезаписи нового студента с таким же статусом, который будет найден позже в итерации С другой стороны, что действительно может быть полезной для запроса информации, так это список студентов, которым присвоен статус. Они могут быть сгруппированы с использованием аналогичного потокового конвейера следующим образом:

Map<Status, List<Student>> statusWiseStudent = studentList.stream()
        .flatMap(s -> s.getStatusAndMarks().keySet()
                .stream()
                .map(status -> new AbstractMap.SimpleEntry<>(status, s)))
        .collect(Collectors.groupingBy(Map.Entry::getKey,
                Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
1 голос
/ 30 марта 2020

Вы можете попробовать что-то вроде этого:

studentList.stream()
        .flatMap(student -> student.getStatusAndMarks()
                .keySet().stream().map(status -> Map.entry(status, student)))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

Map.entry от Java 9. Для более низких Java его можно заменить на:

status -> new AbstractMap.SimpleEntry(status, student)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...