Java 填充地图';s值与使用流的另一个列表中的值

Java 填充地图';s值与使用流的另一个列表中的值,java,java-8,java-stream,Java,Java 8,Java Stream,假设我有一个类型为map的映射和一个类型为list的列表。如何使用流使用list中的元素填充地图的列表值(最初为空列表) 字符串键应该是一门课程(如数学或英语),每个学生都有一套包含他们所有课程的设置。我想用每门课程作为地图上的一个键,它的值是所有参加该课程的学生的列表 这是我的密码: studentMap.entrySet().stream() .map(entry -> entry.getValue()). collect(studentList.stream().map(studen

假设我有一个类型为
map
的映射和一个类型为
list
的列表。如何使用流使用
list
中的元素填充地图的列表值(最初为空列表)

字符串键应该是一门课程(如数学或英语),每个学生都有一套包含他们所有课程的设置。我想用每门课程作为地图上的一个键,它的值是所有参加该课程的学生的列表

这是我的密码:

studentMap.entrySet().stream()
.map(entry -> entry.getValue()).
collect(studentList.stream().map(student -> student.getClasses() //Returns a set of that student's courses));

我的代码不起作用,因为我不知道如何从地图的课程键获取学生的课程集。

如果您的要求是只添加到现有的
地图,而不创建新的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
然后,如果确定目标地图具有所有关键点,则可以使用这些关键点进行合并:

for(Map.Entry<String, List<Student>> entry : myMap.entrySet()) {
    map.get(entry.getKey()).addAll(entry.getValue());
}
for(Map.Entry:myMap.entrySet()){
map.get(entry.getKey()).addAll(entry.getValue());
}

我使用嵌套流解决了这个问题:

studentList.stream().forEach(
   student-> {
       student.getCourses().stream().
       forEach(courseName -> {
       List<Student> students = studentMap.get(courseName);
       students.add(student);
       studentMap.put(courseName, students);
       });
     }
   );

studentList.stream().forEach(
学生->{
student.getCourses().stream()。
forEach(课程名称->{
List students=studentMap.get(courseName);
学生。添加(学生);
学生地图。放置(课程名称,学生);
});
}
);

我对Java 8上的流和收集函数还不是很熟悉,但是如果您启动列表上的流比启动studentMap好吗?我使用并行流和forEach函数编写了下面的代码。让我知道这是否是你要找的。如果您有更高级的Java 8使用来满足您的需求,请让我知道。我也想提高我对Java8的认识

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);
        }

    });
List students=new ArrayList();
添加(新学生(“a”,“数学”));
添加(新学生(“b”,“数学”));
添加(新学生(“c”、“科学”);
添加(新学生(“d”、“科学”);
Map Map=newhashmap();
students.parallelStream().forEach(student->{
字符串课程=student.course;
if(map.get(course)!=null){
地图。获取(课程)。添加(学生);
}否则{
List filteredStudent=new ArrayList();
filteredStudent.add(学生);
地图放置(课程,过滤学生);
}
});

勾选此处,使您的地图最初有一些KVP,并且您希望向这些KVP的值添加内容。您不想创建新的映射,也不想创建新的KVP。正确吗?@Sweeper正确。当您所做的只是
forEach
时,您不需要流。此外,当您添加到已包含在
映射中的
列表
时,无需再次将其放入
。因此,您的代码可以简化为
studentList.forEach(student->student.getCourses().forEach(courseName->studentMap.get(courseName).add(student))
flatMapping
收集器的完美案例…
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);
        }

    });