@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));
});
答案 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())));