映射列表并将其映射到地图中

时间:2020-03-30 13:43:52

标签: java java-8 java-stream

@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中以功能样式编写以上编写的代码? 我已经编写了以下代码,但是如何编写代码的结果是不可变的映射,并且不需要在lambda之前创建映射?

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

2 个答案:

答案 0 :(得分:1)

您可以尝试以下操作:

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来自Java9。对于较低版本的Java,可以将其替换为:

status -> new AbstractMap.SimpleEntry(status, student)

答案 1 :(得分:1)

如果您再次使用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())));
相关问题