Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java API Streams collecting stream in Map where value is a TreeSet

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>()))`.
like image 363
False Promise Avatar asked Feb 04 '18 14:02

False Promise


People also ask

How do you collect a stream from a map?

Method 1: Using Collectors.toMap() Function The Collectors. toMap() method takes two parameters as the input: KeyMapper: This function is used for extracting keys of the Map from stream value. ValueMapper: This function used for extracting the values of the map for the given key.

Can we apply streams to map in Java?

Yes, you can map each entry to another temporary entry that will hold the key and the parsed integer value. Then you can filter each entry based on their value. Map<String, Integer> output = input. entrySet() .

What does stream () map do?

Stream map() in Java with examples Stream map(Function mapper) returns a stream consisting of the results of applying the given function to the elements of this stream. Stream map(Function mapper) is an intermediate operation.

How map is used in stream API?

The map() function is a method in the Stream class that represents a functional programming concept. In simple words, the map() is used to transform one object into another by applying a function. That's the reason the Stream. map(Function mapper) takes a function as an argument.


2 Answers

students.stream()
        .collect(Collectors.groupingBy(
                Student::getAge,
                Collectors.mapping(
                      Student::getSurname, 
                      Collectors.toCollection(TreeSet::new))           
))
like image 190
Eugene Avatar answered Oct 16 '22 09:10

Eugene


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;
                        }));
like image 21
Ousmane D. Avatar answered Oct 16 '22 08:10

Ousmane D.