4

私は Java の初心者であり、Java のジェネリックについてはさらに初心者です。同様の質問を探しましたが、特定の問題に対する簡単な答えは見つかりませんでした。

私は、患者、医師、相談、医療イベント、および診療所に関連するすべてのものを管理するプロジェクトを開発しています。私が今やろうとしているのは、各患者に関連する医療イベントのリストを作成することです. この医療イベントのリストには、今のところ、検査と処方箋の追加のみが許可されているはずですが、拡張可能である必要があります。将来、必要に応じて他の種類の医療イベントを追加できるようにしたいと考えています。手術に関する情報など。

そこで、Patient クラスにジェネリック ArrayList の ArrayList を作成することから始めました。その型は、MedicalEvent クラスによって拡張されるように制限されています (つまり、今のところ、これは Prescription または Exam のいずれかの型の ArrayList の ArrayList です)。また、Prescription タイプの ArrayList と、Exam タイプの別の ArrayList も作成しました。

List<ArrayList<? extends MedicalEvent>> medicalevents;

private ArrayList<Prescription> prescriptions;

private ArrayList<Exam> exams;

次に、コンストラクターで、ArrayLists 処方箋と検査を ArrayList medicalevents に追加しました。

medicalevents.add(prescriptions);

medicalevents.add(exams);

許可されている 2 つのタイプのいずれかの医療イベントを追加するために、次のメソッドを定義しました。

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 MedicalEvent) は、引数 (処方箋) には適用できません」というエラーが表示され、その意味がわかりません。誰かが私が間違っていることを教えてくれますか、またはこの問題に取り組むためのより良い方法を提案できますか?

ありがとう!

4

2 に答える 2

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

Bに追加することはできませんas。後でリストから読み取ろうとするときに問題が発生するためです。

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元の問題について-コードを変更して、 用と用の 2 つの異なるリストがあるようにすることができますExamこれらの 2 つのリストを反復処理して何か便利なことを行うメソッドを1 つだけ使用することもできます(コンテンツの印刷など)。

void doSomethingWithEvents(List<? extends Event> events) {
}
于 2012-12-01T15:30:48.560 に答える
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;
        }
    }
}
于 2012-12-01T15:37:49.857 に答える