我有以下代码:
public abstract class Heap {
Comparable<?> data[];
int count, size;
public Heap( int size ) {
this.size = size;
data = new Comparable<?>[ size + 1 ];
this.count = 0;
}
public abstract void insert( Comparable<?> item );
}
class MinHeap extends Heap {
public MinHeap (int size ) { super(size); }
public void insert( Comparable<?> item ) {
//this line here is giving me an error
//due to how I am storing the array in Heap
int k = data[ 0 ].compareTo( item );
}
}
上面指出的行给了我这个错误:The method compareTo(capture#1-of ?) in the type Comparable<capture#1-of ?> is not applicable for the arguments (Comparable<capture#2-of ?>)
。在维持这些条件时,我无法找到使其工作的方法:1)我希望MinHeap使用任何实现Comparable
的数据,2)我不想将预先初始化的数组传递给构造函数。我这样说是因为我不想做以下事情:
abstract class Heap< T extends Comparable<T> > {
T data[];
public Heap( T data[], int size ) {
this.data = data;
//I do not want to have to pass an instantiated array.
//I want the constructor to handle the instantiation. If I do this I know the issue with the
//compareTo will be solved, but I really prefer to avoid this.
}
}
我的问题是:在我的代码中,为什么我会收到此错误?有没有人知道除了第二个例子中描述的方式之外的方式?我希望能够创建具有任何可比数据的最小堆数据结构。所有有用的评论都表示赞赏。谢谢。
附注:不要担心实例变量的访问修饰符。为简单起见,我将它们保留为默认值我知道他们应该是私人的setter / getters或protected。
答案 0 :(得分:1)
首先,此代码对于创建通用数组无效:
data = new Comparable<?>[ size + 1 ];
This link in the Java Trails解释了为什么它是非法的,但它归结为数组必须在编译时知道它们的类型,并且泛型基于类型擦除而工作,并且可以在运行时推断。
但在我们解决这个问题之前,您的仿制药存在问题 - 它们并非真正......通用。您只在此使用通配符通用,没有边界。
如果你想让你的抽象类包含一个充满Comparable
的泛型数组,那么你希望你的抽象类绑定到Comparable<T>
,并让你的数据被绑定到T
。有了这个,我们最终可以将数组初始化修复为可编译(但未经检查的强制转换)形式:
data = (T[]) new Comparable[size + 1];
这里是完整的课程供参考。它会关闭到您的第二个表单,并且不要求您传入实例化的数组。此外,由于T
绑定到Comparable<T>
,我们不需要将其声明为方法中的参数 - 我们只需提供T
。
public abstract class Heap<T extends Comparable<T>> {
T data[];
int count, size;
public Heap(int size) {
this.size = size;
data = (T[]) new Comparable[size+1];
this.count = 0;
}
public abstract void insert(T item);
}
除此示例之外,您还希望将泛型类型添加到子类中:
class MinHeap<T extends Comparable<T>> extends Heap<T>
答案 1 :(得分:1)
试试这个:
compareTo()
返回int
而不是boolean
值。public abstract void insert( Comparable<?> item );
错了。List
。有关详细信息,请参阅How to create a generic array? 示例代码:
abstract class Heap<T> {
List<Comparable<T>> data;
public Heap(int size) {
data = new ArrayList<Comparable<T>>();
}
public abstract void insert(T item);
}
class MinHeap<T extends Comparable<T>> extends Heap<T> {
public MinHeap(int size) {
super(size);
}
public void insert(T item) {
int k = data.get(0).compareTo(item);
}
}
答案 2 :(得分:0)
您的数据可以包含任何类型的对象,只要它的类实现Comparable即可。所以你可以在数组中包含字符串,整数,长整数或香蕉。
将整数与字符串或香蕉进行比较并不合理。这就是编译器不能编译此代码的原因。
第二种方式是正确的方式。您可以在内部使用对象数组,并将每个对象强制转换为T
。如果所有方法只接受T的实例,则保证转换成功。或者你可以使用List,它比数组更加通用。