Search code examples
javalambdajava-8java-stream

Java convert a list to a map of sets with grouping by key


Say I have a list of objects called Student. Object Student is defined as

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

In the list of students, there can be multiple student objects with the same studentName but different courseTaking. Now, I want to turn the list of students into a map of studentName and courseTaking like so

Map<String, Set<String>>

The key is studentName, and the value is all of the courseTaking of the same student put together as a Set. How can I do this using stream() & collect()?


Solution

  • I think this is what you're looking for:

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

    yeilds {Andreas=[Kotlin 205], Zoff=[Java 101, CompSci 104, Lit 110]}