简体   繁体   English

如何访问通用ArrayLists的ArrayList中的对象

[英]How to access the objects inside an ArrayList of generic ArrayLists

I'm new to Java, and even newer to generics in Java. 我是Java的新手,甚至是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). 因此,我首先在Patient类中创建一个通用ArrayLists的ArrayList,其类型有限,由MedicalEvent类扩展(因此,现在,它是Prescription或Exam类型的ArrayLists的ArrayList)。 I also created an ArrayList of type Prescription and another of the type Exam. 我还创建了一个Prescription类型的ArrayList和另一个类型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. 然后,在构造函数中,我将ArrayLists处方和检查添加到ArrayList医疗事件中。

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. 问题是,我得到错误“方法添加(捕获#1-of?extends MedicalEvent)类型ArrayList不适用于参数(处方)”,我不知道它的含义。 Can anyone tell me what I am doing wrong, or suggest a better way to tackle this problem? 任何人都可以告诉我我做错了什么,或建议更好的方法来解决这个问题?

Thanks! 谢谢!

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: 你不能将B添加为as ,因为稍后当你尝试从列表中读取时会引起问题:

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> 一般来说,像List<? extends Something>这样的有界通配符的集合 List<? extends Something> are useful for code which won't modify collection, but just iterate over it doing something with elements. List<? extends Something>对于不会修改集合的代码很有用,但只是迭代它对元素做一些事情。

Regarding your original problem -- you can change code so there are two distinct lists, one for Prescription , another for Exam . 关于您的原始问题 - 您可以更改代码,因此有两个不同的列表,一个用于Prescription ,另一个用于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) {
}

Would something like this work better? 这样的事情会更好吗?

class Medical {
    List<EventList<?>> eventLists = new ArrayList<EventList<?>>();

    Medical() {
        eventLists.add(new EventList<Perscription>(Perscription.class));
        eventLists.add(new EventList<Exam>(Exam.class));
    }

    boolean add(Object item) {
        for(EventList<?> list : eventLists) {
            if(list.tryToAdd(item)) {
                return true;
            }
        }
        return false;
    }
}

class EventList<T> {
    Class<T> type;
    List<T> list = new ArrayList<T>();

    EventList(Class<T> type) {
        this.type = type;
    }

    boolean tryToAdd(Object item) {
        if(type.isInstance(item)) {
            list.add(type.cast(item));
            return true;
        } else {
            return false;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM