在使用linkedlist(实际上是内部类Node
)实现优先级队列时,我对insert()
和max()
方法进行了如下编码。它使用惰性方法,即保持项目无序,然后仅在发生max()
或deleteMax()
调用时才搜索最大元素。
public class LinkedListMaxPQ<Item extends Comparable<Item>>{
private int N;
private Node head;
public void insert(Item item) {
Node old = head;
head = new Node();
head.item = item;
head.next = old;
N++;
}
public Item max() {
Item maxitem = (Item) this.head.item;
for(Node t=head.next;t!=null;t=t.next){
if(gt(t.item,maxitem)){
maxitem = (Item) t.item;
}
}
return maxitem;
}
private boolean gt(Comparable x,Comparable y){
return x.compareTo(y) > 0;
}
private class Node<Item extends Comparable<Item>>{
Item item;
Node next;
}
}
我想知道为什么我需要Item maxitem = (Item) this.head.item
的演员阵容?由于该类使用泛型类型Item which extends Comparable
,而内部类也使用Item extends Comparable,因此可能会认为这样的强制转换是不必要的。
如果我省略铸造
Item maxitem = this.head.item;
编译器会抱怨类型不匹配
类型不匹配:无法从可比较项转换为项目
有人能解释为什么会发生这种情况吗?
因为Java将Item
视为Node
类声明中的类型参数(与LinkedListMaxPQ<Item extends Comparable<Item>>
中声明的Item
类型参数无关)。
此声明-
private class Node<Item extends Comparable<Item>>{
Item item;
Node next;
}
告诉编译器您正在创建一个私有类,该类具有名为Item
的类型参数,并且是Comparable<Item>
的子类型。在类型擦除期间,该Item
将被其类型为Comparable
的绑定所取代。这就是为什么你需要明确的演员阵容。
此外,以下行-
private Node head;
创建一个原始类型Node
,但没有任何可用的类型信息。您应该得到这一行的警告。
要解决此问题,请按以下方式声明您的head
-
private Node<Item> head;
并以以下方式创建实例-
head = new Node<Item>(); // if you are using jdk 6 or lesser
head = new Node<>(); // if you are using jdk 7
以类似的方式更新所有Node
引用,您的警告应该会消失。
如果你需要进一步澄清类型参数绑定,你可以阅读我的一篇博客文章,我试图解释类型参数绑定是如何工作的。
您需要
private class Node{
...
通过将其作为:
private class Node<Item extends Comparable<Item>>{
您正在生成一个名为Item
的新的泛型类型,该类型与封装类的Item
类型不同,尽管它具有相同的名称。
它很简单,因为您在创建head时没有指定类型,node.head有类型对象
这应该可以解决的问题
public class LinkedListMaxPQ<Item extends Comparable<Item>>{
private int N;
private Node<Item> head;
public void insert(Item item) {
Node<Item> old = head;
head = new Node<Item>();
head.item = item;
head.next = old;
N++;
}
public Item max() {
Item maxitem = this.head.item;
for(Node<Item> t=head.next;t!=null;t=t.next){
if(gt(t.item,maxitem)){
maxitem = t.item;
}
}
return maxitem;
}
private class Node<Item extends Comparable<Item>>{
Item item;
Node<Item> next;
}
}
t
变量的声明更改为Node<Item>
:
for (Node<Item> t = head.next; t != null; t = t.next){
if (gt(t.item, maxitem)){
maxitem = t.item;
}
}
第二个选项:如果您想引用与父LinkedListMaxPQ
类中相同的类型,则从Node
类定义中删除类型参数:
public class LinkedListMaxPQ<Item extends Comparable<Item>> {
...
private class Node {
Item item;
Node next;
}
}