鉴于我有一个Map<String, List<Student>>
类型的映射和一个List<Student>
类型的列表。如何使用流使用List<Student>
中的元素填充地图的列表值(最初是空列表)?
“字符串”键应该是一门课程(例如数学或英语),并且每个学生都有一个包含其所有课程的集合。我想将每门课程用作地图中的键,其值是所有参加该课程的学生的列表。
这是我的代码:
studentMap.entrySet().stream()
.map(entry -> entry.getValue()).
collect(studentList.stream().map(student -> student.getClasses() //Returns a set of that student's courses));
我的代码不起作用,因为我不知道如何从地图的课程键中获取一组学生的课程。
答案 0 :(得分:1)
如果您的要求是仅添加到现有的Map
而不创建新的KVS,则可以尝试如下操作:
Map<String, List<Student>> map = new HashMap<>();
students.stream()
.flatMap(student -> student.getClasses().stream().map(classname -> new AbstractMap.SimpleEntry<>(classname, student)))
.forEach(entry -> map.get(entry.getKey()).add(entry.getValue())); // use it if you are completly sure that there is a key for this class in your map
但是,它混合了“流”和“迭代”方法,并修改了流之外的Map
,这使其产生副作用。
如果您想直接将List
转换为新的Map
,则可以使用:
Map<String, List<Student>> myMap = students.stream()
.flatMap(student -> student.getClasses().stream().map(classname -> new AbstractMap.SimpleEntry<>(classname, student)))
.collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toList())));
然后,如果您确定目标地图具有所有键,则可以使用它来合并:
for(Map.Entry<String, List<Student>> entry : myMap.entrySet()) {
map.get(entry.getKey()).addAll(entry.getValue());
}
答案 1 :(得分:0)
我用嵌套流弄清楚了:
studentList.stream().forEach(
student-> {
student.getCourses().stream().
forEach(courseName -> {
List<Student> students = studentMap.get(courseName);
students.add(student);
studentMap.put(courseName, students);
});
}
);
答案 2 :(得分:-1)
我对Java 8上的流和收集函数还不是很熟悉,但是如果您在List上启动流,那么它比StudentMap好吗?我在下面使用并行流和forEach函数编写了代码。让我知道这是否是您想要的。如果您更高级地使用Java 8来满足您的要求,请告诉我。我也想提高对Java 8的了解。
List<Student> students = new ArrayList<Student>();
students.add(new Student("a", "Math"));
students.add(new Student("b", "Math"));
students.add(new Student("c", "Science"));
students.add(new Student("d", "Science"));
Map<String, List<Student>> map = new HashMap<String, List<Student>>();
students.parallelStream().forEach(student ->{
String course = student.course;
if(map.get(course) != null) {
map.get(course).add(student);
}else {
List<Student> filteredStudent = new ArrayList<Student>();
filteredStudent.add(student);
map.put(course, filteredStudent);
}
});