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.
source share