0

次のように、同じ型の 2 つの変数を格納する非常に単純なジェネリック クラスを作成しました。

public MyClass<T>
{
    private T v1;
    private T v2;

    public MyClass(T v1, T v2)
    {
      this.v1 = v1;
      this.v2 = v2;
    {
 }

ここで、別の非ジェネリック クラスを介して、異なる型の Object リストを入力として取り、出力としてMyClass<T>同じ型のペアを持つリストを与えるメソッドを実装する必要があります。

私の問題は、どのタイプを使用しているかを知らずにこのようなものを作成する方法がわからないことMyClassです。毎回適切なタイプをインスタンス化するにはどうすればよいですか? 日食からエラーが発生することなく、ここまで来ました

public List<MyClass<?>> match()
{
    List<MyClass<?>> list = new ArrayList<MyClass<?>>();

    for(Object obj : this.list)//not the same list it's a parameter of the
    {                     //non-generic class
        for(Object obj2 : this.list)
        {
            if(!(obj == obj2)&&obj.getClass().equals(obj2.getClass()))
            {
                MyClass<Object> couple = new MyClass<Object>(obj, obj2);
                insertCouple(couple, list);
            }
        }
    }

insertCoupleカップルが既に出力リストにあるかどうかを確認するプライベートメソッドです。実装しようとしComparableましMyClassたが、コーディングがさらに複雑になりました。

ご覧のとおり、私はジェネリックのままでいることを余儀なくされていますが、問題があることがわかります。実行時に特定の型を見つけて埋める方法がない場合、ジェネリックを介してそれを可能にするためにどのように書く必要がありますか?

4

2 に答える 2

1

コメントで収集できたものから、解決策は、述語に基づいて、入力リストから要素のペアのリストを作成することです。

class Match<T>
{
    T a, b;

    Match(T a, T b)
    {
        this.a = a;
        this.b = b;
    }
}

<T> List<Match<T>> match(List<T> list)
{
    List<Match<T>> matchList = new ArrayList<Match<T>>();

    for(T a : list)
    {
        for(T b : list)
        {
            if(a != b && a.getClass().equals(b.getClass()))
            {
                matchList.add(new Match<T>(a, b));
            }
        }
    }

    return matchList;
}

私はあなたの要件を満たしていると信じています:

ここで、別の非ジェネリック クラスを介して、異なる型のオブジェクト リストを入力として取り、同じ型の対を持つ MyClass のリストを出力として与えるメソッドを実装する必要があります。

上記のコードを含むクラスはジェネリックである必要がないmatchため、メソッドは の暗黙的な指定で呼び出すことができます。たとえば、それTを知っTたり指定したりする必要はありません。実際にはmatch、単にList<Object>or List(レガシー コード) もしよろしければ。唯一の制限は、返されるリストがaList<Match<K>>を呼び出したときと同じように入力されることですが、これは良いことです。ここではジェネリックが適切に適用されます。matchList<K>

match述語パラメーターを操作することで、 をカスタマイズすることもできます。

class Predicate
{
    <T> boolean eval(T a, T b)
    {
        return a != b && a.getClass().equals(b.getClass());
    }
}

<T> List<Match<T>> match(List<T> list, Predicate predicate)
{
    List<Match<T>> matchList = new ArrayList<Match<T>>();

    for(T a : list)
    {
        for(T b : list)
        {
            if(predicate.eval(a, b))
            {
                matchList.add(new Match<T>(a, b));
            }
        }
    }

    return matchList;
}

最後のアドバイスとして、ジェネリック クラスの型パラメーターを省略することは避けてください。putObjectまたは?どこでも行うのが最も簡単な方法ですが、ほとんどの場合、これらのジェネリック仕様に真に一致する型を見つけようとする方が適切です。

于 2013-05-24T10:54:59.437 に答える
1

すべてのジェネリック型はコンパイル時に消去されるため、(一致したオブジェクトのクラスに応じて) 実行時に作成する MyClass オブジェクトの型を決定することはできません。型消去の詳細については、次を参照してください。

http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

于 2013-05-23T12:09:18.467 に答える