Java将一个列表转换为一个按键分组的集合映射

11

假设我有一个名为Student的对象列表。对象Student的定义如下:

public Class Student {
    private String studentName;
    private String courseTaking;
}

在学生列表中,可能会有多个具有相同 studentName 但不同 courseTaking 的学生对象。现在我想将学生列表转换为 studentName 和 courseTaking 的映射表,如下所示:
Map<String, Set<String>>

关键是studentName,值是同一学生参加的所有courseTaking组合在一起形成一个集合。我如何使用stream() & collect()来实现这个功能?


当你问如何“使用lambda表达式”来实现它时,你实际上是想问如何使用Streams来实现吗?因为可以使用Streams和方法引用(假设getter方法存在)来完成它,而不需要任何lambda表达式,所以问题就在于为什么必须使用lambda表达式呢? - Andreas
是的,我本意要使用stream()。抱歉第一版没有表达清楚。我可以使用groupBy()将列表转换为列表映射,但我无法弄清如何将其转换为集合映射。 - Zoff
那么你为每个学生所选的课程重复创建了“学生”对象?这绝对不是正确的做法。应该直接将课程作为“学生”对象中的一个数组。 - Isac
3
students.stream().collect(groupingBy(Student::getStudentName, mapping(Student::getCourseTaking, toSet()))) - shmosel
1个回答

11

我认为这就是你在寻找的东西:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


public class StackOverflow {

  private static class SO46310655 {
    public static void main(String[] args) {
      final List<Student> students = new ArrayList<>();
      students.add(new Student("Zoff", "Java 101"));
      students.add(new Student("Zoff", "CompSci 104"));
      students.add(new Student("Zoff", "Lit 110"));
      students.add(new Student("Andreas", "Kotlin 205"));
      Map<String, Set<String>> map = students.stream().collect(
          Collectors.groupingBy(
              Student::getStudentName,
              Collectors.mapping(
                  Student::getCourseTaking,
                  Collectors.toSet()
              )
          )
      );
      System.out.println(map);
    }

    public static class Student {
      private final String studentName;
      private final String courseTaking;

      public Student(String studentName, String courseTaking) {
        this.studentName = studentName;
        this.courseTaking = courseTaking;
      }

      public String getStudentName() {
        return studentName;
      }

      public String getCourseTaking() {
        return courseTaking;
      }
    }
  }
}

产生 {安德烈亚斯=[Kotlin 205], 索夫=[Java 101, 计算机科学 104, 文学 110]}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接