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(),我需要能够比较两个 T。先验似乎可能的一种选择是告诉编译器 T 实现了 Comparable。但是,如果我输入 replace < T > with < T implements Comparable > 编译器会抱怨——我该怎么做呢?

或者,我可以定义一个类

public class HasValue{

  int value;

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

}

理论上我应该能够比较两个 HasValue 对象,如 x.value > y.value。但是如果我输入

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

在第二种情况下T extends HasValue被抹去,HasValue所以你需要有。

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

恕我直言,Java 不允许new T[HEAP_SIZE]做你必须做的事情是不必要的迂腐。

于 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 回答