First, I'll assume that if a Patient has visited a Department more than once, that Department will appear in the Patient's history list more than once.
If that's the case, then we can simply take our Stream of Patients and flatMap
it to a Stream of Departments, where the occurrence of a Department indicates one visit from a Patient.
Then we can pass this to the groupingBy
collector. We want to classify by Department itself, so the classifier function is the identity function.
For the value, we want to put a 1 as the value if an entry for the Department isn't present yet, but we want to add 1 to the existing value if an entry is present. There's a collector called counting()
that does this for us already, so we just pass it as a downstream collector to groupingBy()
.
The resulting code is as follows:
import static java.util.stream.Collectors.*;
List<Patient> patients = ... ;
Map<Department, Long> frequency =
patients.stream()
.flatMap(p -> p.getHistory().stream())
.collect(groupingBy(d -> d, counting()));
Note that if a Department hasn't been visited, it will simply be absent from the map. If you have a list of departments, you can fill in the zero values like this:
departments.forEach(d -> frequency.putIfAbsent(d, 0L));
or if you want to fill in the zero on the get
side,
long numVisits = frequency.getOrDefault(dept, 0L);