2012-12-01 63 views
4

我是Java新手,甚至是Java中的泛型更新。我寻找过类似的问题,但对于我的特殊问题没有找到直接的答案。如何访问通用ArrayList的ArrayList中的对象

我正在开发一个项目来管理患者,医生,咨询,医疗事件和所有与医疗诊所相关的内容。 我现在要做的是创建与每位患者相关的医疗事件列表。到目前为止,这个医疗事件列表只能被允许添加检查和处方,但它应该是可扩展的:如果需要,我希望能够在未来添加其他类型的医疗事件,如关于手术的信息。因此,我开始在类Patient中创建一个通用ArrayLists的ArrayList,其类型有待由类MedicalEvent扩展(所以,现在,它是ArrayList类型的Prescription或Exam类型ArrayList)的ArrayList。我还创建了一个Prescription类型的ArrayList和另一个类型的Exam。

List<ArrayList<? extends MedicalEvent>> medicalevents;

private ArrayList<Prescription> prescriptions;

private ArrayList<Exam> exams;

然后,在构造函数中,我添加了处方的ArrayList和考试到ArrayList medicalevents。

medicalevents.add(prescriptions);

medicalevents.add(exams);

要添加两种允许的类型之一的医疗事件,我定义了以下方法:

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); 
    } 
} 

的问题是,我得到的错误“的方法在类型ArrayList中添加(捕获#1-of?extends MedicalEvent)不适用于参数(处方)“,我不知道它是什么意思。任何人都可以告诉我我做错了什么,或者建议更好的方法来解决这个问题?

谢谢!

+0

是'处方'是'MedicalEvent'的孩子吗? –

+0

是的,这是正确的。 –

+0

这是关于你的问题的主题,但我认为使用地图<?扩展MedicalEvent,List <?扩展MedicalEvent >>比拥有列表清单(比如你)要好得多,因为它需要你对索引进行硬编码。 – pabrantes

回答

7

鉴于以下声明

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 
    } 
} 

不能添加到Bas,因为它会在以后造成的问题,当你试图从名单如下:

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

要更好地理解这个问题有有趣的例子:

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(); 

通常,带有限制通配符(如List<? extends Something>)的集合对于不会修改集合的代码非常有用,但只需对它进行迭代就可以对元素进行一些操作。

关于您的原始问题 - 您可以更改代码,以便有两个不同的列表,一个用于Prescription,另一个用于Exam。你仍然可以拥有只一个方法,它会遍历这两个列表做一些事情(如打印内容他们)有用:

void doSomethingWithEvents(List<? extends Event> events) { 
} 
+0

我想我会去清楚清单。现在我想到了,这简单得多,通用性也是一样的。谢谢,这确实有帮助。 –

+0

有关于泛型主题的Oracle Java教程:http://docs.oracle.com/javase/tutorial/java/generics/。除了其他内容之外,它还有关于您的问题的专门页面:http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html和http://docs.oracle.com/javase/tutorial/的java /泛型/ subtyping.html –

1

会像这样工作更好吗?

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; 
     } 
    } 
} 
相关问题