2

一般的な最大ヒープの簡単な実装を書いています。私が書いたら

public class FastMaxHeap<T>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(){
    data = (T[]) new Object[HEAP_SIZE];
  size = 0;
  }
}

コンパイルします。ヒープを実際に実装するには、つまり maxHeapify() を記述するには、2 つの T を比較できる必要があります。アプリオリに可能と思われるオプションの 1 つは、T が Comparable を実装していることをコンパイラに伝えることです。しかし、replace < T > with < T implements Comparable > と入力すると、コンパイラは文句を言います - どうすればこれを行うことができますか?

または、クラスを定義することもできます

public class HasValue{

  int value;

  public HasValue(int value){
        this.value = value;
  }

}

理論的には、x.value > y.value のように 2 つの HasValue オブジェクトを比較できるはずです。しかし、私がタイプすると

public class FastMaxHeap<T extends HasValue>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(){
    data = (T[]) new Object[HEAP_SIZE];
  size = 0;
  }
}

ClassCastException が発生するようになりました。ここで何が起こっているのですか?Javaジェネリックは私の脳を傷つけます。

4

4 に答える 4

5

最初のケースでは、実行時T extends Objectに消去されます。Object

2番目のケースT extends HasValueでは消されHasValueてしまうので、持っておく必要があります。

data = (T[]) new HasValue[HEAP_SIZE];

IMHOnew T[HEAP_SIZE]とにかく、Javaがあなたがしなければならないことをすることを許可していないのは、不必要に衒学的です。

于 2012-12-19T20:30:57.473 に答える
0

これを試すことができます(まだコンパイルされていません)

public class FastMaxHeap<T extends HasValue>{

  HasValue[] data;
  int size;

  static final int HEAP_SIZE = 10000;

   public FastMaxHeap(){
     data = new HasValue[HEAP_SIZE];
     size = 0;
   }
}
于 2012-12-19T20:34:08.413 に答える
0

このような配列を作成するには、型トークンを使用することをお勧めします

public class FastMaxHeap<T>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(Class<T> clazz){
    data = (T[])Array.newInstance(clazz, HEAP_SIZE);
    size = 0;
  }
}

このようにして、実行時に ClassCastExceptions が発生しなくなります

また:< T implements Comparable >は正しくありません。正しいものは< T extends Comparable >

于 2012-12-19T20:50:35.637 に答える
0

ヒープは Comparator< T > をコンストラクター引数として受け入れる必要があります。問題が解決しました。クライアントは、任意のタイプを使用できます。Comparable を既に実装している型 T のコンパレータ実装を推論する単純なオーバーロードを指定することもできます。

于 2012-12-19T20:51:31.623 に答える