3

I have a collection (as hashmap) of Doctors, into a generic Hospital class.

Map<Integer, Doctor> doctors = new HashMap<Integer, Doctor>();

For each doctor I have some information such as in the class code (focus on the patients):

public class Doctor extends Person {
    private int id;
    private String specialization;
    private List<Person> patients = new LinkedList<Person>();

My purpose is to write this function which return busy doctors: doctors that has a number of patients larger than the average.

/**
 * returns the collection of doctors that has a number of patients larger than the average.
 */
Collection<Doctor> busyDoctors(){

    Collection<Doctor> doctorsWithManyPatients = 
            doctors.values().stream()
            .map( doctor -> doctor.getPatients() )
            .filter( patientsList -> { return patientsList.size() >= AvgPatientsPerDoctor; })
            .collect(Collectors.toList());

    return null;
}

I want to use the streams as above to perform this operation. The problem is in collect method because at that point of usage doctorsWithManyPatients is of type List<Collection<Person>> and not Collection<Doctor>. How could I do that?

Assume that AvgPatientsPerDoctor is already defined somewhere.

1 Answer 1

4

You needn't use map (Doctor -> List<Person>), it will be used in the filter:

doctors
    .values()
    .stream()
    .filter( d -> d.getPatients().size() >= AvgPatientsPerDoctor)
    .collect(Collectors.toList());

For your case, map( doctor -> doctor.getPatients() ) returns Stream<List<Person>> and you should convert it to Stream<Doctor> again after filtering and before calling the collect method.


There is a different way that isn't the best one. Keep in mind that it changes the origin collection.

doctors.values().removeIf(d -> d.getPatients().size() < AvgPatientsPerDoctor);
4
  • You right. I understood. Thank you for the response. There is a way eventually to convert it to Stream<Doctor> as you mentioned? It is not really nedeed but just to know. Commented May 24, 2016 at 16:48
  • 1
    @GiuseppeCanto, if you have a constructor (or a method - name it as creator) which receives List<Person> and creates a new object of Doctor type Commented May 24, 2016 at 16:53
  • 1
    @GiuseppeCanto, then you could write map(this::creator) or map(list -> this.creator(list)) Commented May 24, 2016 at 16:55
  • So cool. I did not know the .removeIf. Anyway there is an eventual possibility to use it executing a copy of the hashMap, without modify the doctors hashMap. But as you said the first is preferable: the cost on performing a copy is not comparable to the previous one. Thank you again for the other option. I learned one more thing. Commented May 24, 2016 at 17:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.