11

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()?

4
  • When you ask how to do it "using lambda expressions", do you actually mean to ask how to do it using Streams? Because it can be done with Streams and method references (assuming getter methods exist), without any lambda expressions, so the question to you would be why it has to use lambda expressions? Commented Sep 19, 2017 at 22:41
  • Yeah I did mean to use stream(). Sorry for not being clear in the first draft. I can turn the list into a map of list using groupBy(), but I can't figure out how to turn that into a map of set. Commented Sep 19, 2017 at 22:48
  • So you have repeated Student objects for each course the student is taking ? Definitely doesn't feel right. The courses should be an array in the Student object directly. Commented Sep 19, 2017 at 22:48
  • 3
    students.stream().collect(groupingBy(Student::getStudentName, mapping(Student::getCourseTaking, toSet()))) Commented Sep 19, 2017 at 22:49

1 Answer 1

12

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

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.