Stuck with lambda java8 expression

I have Map<Integer,Doctor> docLib=new HashMap<>(); to save the Doctor class.

Class Doctor has methods:getSpecialization() returns a String ,
getPatients( ) to return a collection of the Person class.

In the main method, I type:

 public Map<String,Set<Person>> getPatientsPerSpecialization(){ Map<String,Set<Person>> res=this.docLib.entrySet().stream(). map(d->d.getValue()). collect(groupingBy(d->d.getSpecialization(), d.getPatients()) //error ); return res; } 

As you can see, I have a problem with groupingBy , I'm trying to send the same d value to the method, but this is wrong. How to solve this?

+6
source share
2 answers

To do this, you need a second mapping builder :

 public Map<String,Set<Person>> getPatientsPerSpecialization(){ return this.docLib .values() .stream() .collect(Colectors.groupingBy(Doctor::getSpecialization, Collectors.mapping(Doctor::getPatients,toSet())) ); } 

EDIT:

I think that my original answer may be wrong (it’s hard to say without being able to verify it). Since Doctor::getPatients returns a collection, I think my code can return Map<String,Set<Collection<Person>>> instead of the desired Map<String,Set<Person>> .

The easiest way to overcome this is to repeat this Map again to create the desired Map :

 public Map<String,Set<Person>> getPatientsPerSpecialization(){ return this.docLib .values() .stream() .collect(Colectors.groupingBy(Doctor::getSpecialization, Collectors.mapping(Doctor::getPatients,toSet())) ) .entrySet() .stream() .collect (Collectors.toMap (e -> e.getKey(), e -> e.getValue().stream().flatMap(c -> c.stream()).collect(Collectors.toSet())) ); } 

There may be a way to get the same result with a single stream pipeline, but I don't see it right now.

+5
source

Instead of groupingBy you can use toMap :

 public Map<String, Set<Person>> getPatientsPerSpecialization() { return docLib.values() .stream() .collect(toMap(Doctor::getSpecialization, d -> new HashSet<>(d.getPatients()), (p1, p2) -> Stream.concat(p1.stream(), p2.stream()).collect(toSet()))); } 

What he does is that he groups doctors by specialization and maps them to each set of patients (so Map<String, Set<Person>> ).

If, when collecting data from the pipeline, you encounter a doctor with a specialization that is already stored as a key on the map, you use the merge function to create a new set of values ​​with both sets (a set that is already stored as a value for the key and the set that you want to associate with the key).

+2
source

Source: https://habr.com/ru/post/989436/


All Articles