3

私は classFirstClass<O>とclass を持っていて、 O[] をfrom から呼び出されるルーチン内SecondClass<O>に作成したいと考えています。ここで、O はジェネリック クラス パラメータです。これを行う方法が見つかりません。SecondClass<O>FirstClass<O>

ArrayList<O>ループの本体内で非常に頻繁に O[] から要素を取得する必要があり、アルゴリズムの実行時間にとって重要であるため、特に O[] が必要です (または同様ではありません)。

ですから、これらの線に沿ったものが欲しいと思います。

public class FirstClass<O> {
    void someRoutine(n and other params) {
        //Do some stuff
        SecondClass<O> = new SecondClass(n, possibly_other_params);
        //Do some stuff
    }
}

public class SecondClass<O> {
    O[] myArray;
    SecondClass<O>(int n, possibly_other_params) {
        //Here the constructor that creates an O[n]
    }
}

Web で見つけたいくつかの方法ですが、私の場合は機能しません。

  • 使用しますO[] array = (O[]) new Object[n];が、コンパイルされません。
  • Object[] array = new Object[n];配列から何かを要求するたびに (O) キャストを使用して実行しますが、これは遅すぎます
  • Array.newInstance(Class<O> type, int n);、 withO o;を使用しますが、 CAP#1 の意味が何であれ、typeではなくtypetype=o.classであると不平を言います...typeClass<CAP#1>Class<O>

最適な実行速度を念頭に置いて、Javaでこれを適切に行うにはどうすればよいですか?

4

4 に答える 4

3

Java のジェネリクスの処理はかなり大まかな形ですが、小さな調整を行う準備ができていれば、目的に近いものを実現できます。参照してください:

public class FirstClass<O> {
    Class<O> type;

    public static <O> FirstClass<O> create(Class<O> type) {
        return new FirstClass<O>(type);
    }

    public FirstClass(Class<O> type) {
        this.type = type;
    }

    public void routine(int size /*, other params */ ) {
        SecondClass<O> instance = new SecondClass<O>(type, size);
    }
}

public class SecondClass<O> {
    public O[] array;

    @SuppressWarnings("unchecked")
    public SecondClass(Class<O> type,int size) {
        array = (O[])Array.newInstance(type,size);
    }
}

そしてユースケース:

FirstClass<Integer> instance = FirstClass.create(Integer.class);
instance.routine(110);

これは大まかな例ですが、このアプローチを使用しなくても同様のことを達成できると確信しています。

于 2012-09-08T05:57:19.937 に答える
1

O[] array = (O[]) new Object[n]; を使用します。しかし、これには配列から何かを要求するたびに (O) キャストが必要なので、これは遅すぎます

何?型の要点は、型から何かを取得するときにキャストを必要としないO[]ということです(O)

于 2012-09-09T08:59:33.927 に答える
0

上から私のコメントを繰り返して、うまくいけばこの質問を回答済みとしてマークします:

これを実際にプロファイリングしましたか?キャスティングは実際にあなたのパフォーマンスの懸念を引き起こしているものですか?Javaのジェネリックは実行時に消去されることを考えると、期待どおりに機能させるための簡単な回避策はここにはありません。期待するAPIに再度アクセスしてから、Javaのジェネリックスを希望どおりに機能させることをお勧めします。

于 2012-09-08T04:56:28.480 に答える
0

ソースコードは次のArrayList.setとおりです。

public E set(int index, E element) {
    rangeCheck(index);

    E oldValue = elementData(index);
    elementData[index] = element;
    return oldValue;
}

確かに、古い要素を取得するために追加のルックアップが行われますが、これは気にする必要はありませんが、これは私たちが話しているランダム アクセスです (読み取り: O(1) 時間)。ArrayList速度が低下していることを示すのに難しい数値がない限り、使用してください。

于 2012-09-08T05:01:26.980 に答える