7

There is a Student class which has name, surname, age fields and getters for them.

Given a stream of Student objects.

How to invoke a collect method such that it will return Map where keys are age of Student and values are TreeSet which contain surname of students with such age.

I wanted to use Collectors.toMap(), but got stuck.

I thought I could do like this and pass the third parameter to toMap method:

stream().collect(Collectors.toMap(Student::getAge, Student::getSurname, new TreeSet<String>()))`.
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
False Promise
  • 478
  • 3
  • 6
  • 13

2 Answers2

8
students.stream()
        .collect(Collectors.groupingBy(
                Student::getAge,
                Collectors.mapping(
                      Student::getSurname, 
                      Collectors.toCollection(TreeSet::new))           
))
Eugene
  • 117,005
  • 15
  • 201
  • 306
1

Eugene has provided the best solution to what you want as it's the perfect job for the groupingBy collector.

Another solution using the toMap collector would be:

 Map<Integer, TreeSet<String>> collect = 
        students.stream()
                .collect(Collectors.toMap(Student::getAge,
                        s -> new TreeSet<>(Arrays.asList(s.getSurname())),
                        (l, l1) -> {
                            l.addAll(l1);
                            return l;
                        }));
Ousmane D.
  • 54,915
  • 8
  • 91
  • 126