Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access the objects inside an ArrayList of generic ArrayLists

I'm new to Java, and even newer to generics in Java. I have looked for similiar questions, but have found no straightforward answer for my particular problem.

I'm developing a project to manage the patients, doctors, consultations, medical events and all the stuff that is associated with a medical clinic. What I am trying to do right now is to create a list of medical events associated to each patient. To this list of medical events, for now, it is only supposed to be allowed to add exams and prescriptions, but it's supposed to be extendable: I want to be able to add other types of medical events in the future if I need to, such as information about surgeries.

So, I started by creating an ArrayList of generic ArrayLists in the class Patient, with its type bounded to be extended by the class MedicalEvent (so, for now, it's an ArrayList of ArrayLists of type either Prescription or Exam). I also created an ArrayList of type Prescription and another of the type Exam.

List<ArrayList<? extends MedicalEvent>> medicalevents;

private ArrayList<Prescription> prescriptions;

private ArrayList<Exam> exams;

Then, in the constructor, I added the ArrayLists prescriptions and exams to the ArrayList medicalevents.

medicalevents.add(prescriptions);

medicalevents.add(exams);

To add medical events of one of the two allowed types, I defined the following method:

public void addMedicalEvent(E element){

if(element instanceof Prescription){
    medicalevents.get(0).add((Prescription)element);
    }
if(element instanceof Exam){
    medicalevents.get(1).add((Exam)element);
    }
}

The problem is, I get the error "The method add(capture#1-of ? extends MedicalEvent) in the type ArrayList is not applicable for the arguments (Prescription)" and I don't know what it means. Can anyone tell me what I am doing wrong, or suggest a better way to tackle this problem?

Thanks!

like image 983
Filipe Avatar asked Feb 18 '23 07:02

Filipe


1 Answers

Given following declarations

class A {}
class B extends A {}
class C extends A {}


public class SOSample {
    public static void main(String[] args) {
        List<List<? extends A>> list = new ArrayList<List<? extends A>>();
        final List<? extends A> as = list.get(0);
        as.add(new B()); // error here
    }
}

you can't add B to as, because it will cause problem later on, when you'll try to read from the list:

A a = list.get(0).get(0); // is a B or C?

To better understand this problem there's funny example:

class Vehicle { void launch(); }
class Car extends Vehicle {}
class NuclearMissile extends Vehicle {}
...
// this is prohibited because of below code
List<? extends Vehicle> cars = new ...
// imagine this is possible...
cars.add(new NuclearMissile());
// now this is possible
cars.get(0).launch();

Generally, collections with bounded wildcards like List<? extends Something> are useful for code which won't modify collection, but just iterate over it doing something with elements.

Regarding your original problem -- you can change code so there are two distinct lists, one for Prescription, another for Exam. You still can have just one method which will iterate over these two lists doing something useful (like printing theirs contents):

void doSomethingWithEvents(List<? extends Event> events) {
}
like image 108
Victor Sorokin Avatar answered May 07 '23 21:05

Victor Sorokin