首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何访问泛型ArrayLists的ArrayList中的对象

如何访问泛型ArrayLists的ArrayList中的对象
EN

Stack Overflow用户
提问于 2012-12-01 23:16:07
回答 2查看 2.1K关注 0票数 4

我对Java是个新手,对Java中的泛型更是新手。我一直在寻找类似的问题,但没有为我的特定问题找到直接的答案。

我正在开发一个项目来管理病人、医生、会诊、医疗活动以及与医疗诊所相关的所有东西。我现在要做的是创建一个与每个患者相关的医疗事件列表。在这个医疗事件列表中,目前只允许添加检查和处方,但它应该是可扩展的:如果需要,我希望将来能够添加其他类型的医疗事件,例如关于手术的信息。

因此,我首先在类Patient中创建了一个泛型ArrayLists的ArrayList,它的类型被绑定为由MedicalEvent类扩展(所以,现在它是一个ArrayLists的ArrayList,类型可以是Prescription,也可以是Exam)。我还创建了一个类型为Prescription的ArrayList和另一个类型为Exam的类型。

List<ArrayList<? extends MedicalEvent>> medicalevents;

private ArrayList<Prescription> prescriptions;

private ArrayList<Exam> exams;

然后,在构造器中,我向ArrayList医疗事件添加了ArrayLists处方和检查。

medicalevents.add(prescriptions);

medicalevents.add(exams);

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

代码语言:javascript
运行
复制
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类型中的方法add(capture#1-of ? extends )不适用于参数(规定)”,但我不知道这是什么意思。有没有人能告诉我我哪里做错了,或者有没有更好的方法来解决这个问题?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-01 23:30:49

给出以下声明

代码语言:javascript
运行
复制
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
    }
}

您不能将B添加到as,因为当您尝试从列表中读取时,它会在稍后引起问题:

代码语言:javascript
运行
复制
A a = list.get(0).get(0); // is a B or C?

为了更好地理解这个问题,这里有一个有趣的例子:

代码语言:javascript
运行
复制
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。你仍然可以只使用一个方法来迭代这两个列表,做一些有用的事情(比如打印它们的内容):

代码语言:javascript
运行
复制
void doSomethingWithEvents(List<? extends Event> events) {
}
票数 7
EN

Stack Overflow用户

发布于 2012-12-01 23:37:50

像这样的东西会工作得更好吗?

代码语言:javascript
运行
复制
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;
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13660754

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档