我正在编写一个通用最大堆的简单实现。如果我写
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&lt; T>与&lt; T实现Comparable&gt;编译器抱怨 - 我该怎么做?
或者,我可以定义一个类
public class HasValue{
int value;
public HasValue(int value){
this.value = value;
}
}
并且理论上我应该能够比较两个HasValue对象,例如x.value&gt; 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泛型伤害了我的大脑。
答案 0 :(得分:5)
第一种情况T extends Object
在运行时被删除为Object
。
在第二种情况下,T extends HasValue
被删除为HasValue
,因此您需要拥有。{/ p>
data = (T[]) new HasValue[HEAP_SIZE];
恕我直言,Java不允许new T[HEAP_SIZE]
做你必须做的事情,这是不必要的迂腐。
答案 1 :(得分: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;
}
}
答案 2 :(得分: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 >
答案 3 :(得分:0)
你的堆应该接受比较器&lt; T>作为构造函数的参数。问题解决了。客户可以使用他想要的任何类型。您还可以提供一个简单的重载,它可以推断已经实现Comparable的类型T的比较器实现。