while implementing a priority queue using a linkedlist(actually an inner class Node
),I coded the insert()
and max()
methods as below.It uses the lazy approach of keeping the items unordered and then seaching through them for the maximum element only when a max()
or deleteMax()
call occurs.
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;
}
}
I am wondering why I need the cast in Item maxitem = (Item) this.head.item
? Since the class uses a generic type Item which extends Comparable
and the inner class also uses Item extends Comparable ,one would think that such a cast is unnecessary.
If I omit the cast
Item maxitem = this.head.item;
compiler will complain that there is a type mismatch
Type mismatch: cannot convert from Comparable to Item
Can someone explain why this occurs?
Because Java is treating Item
as a type parameter in the Node
class declaration (which has no relation to the Item
type parameter declared in LinkedListMaxPQ<Item extends Comparable<Item>>
).
This declaration -
private class Node<Item extends Comparable<Item>>{
Item item;
Node next;
}
tells the compiler that you are creating a private class which has a type parameter called Item
, and which is a subtype of Comparable<Item>
. During type erasure, this Item
will be replaced by its bound, which is of type Comparable
. That's why you need that explicit cast.
Also, the following line -
private Node head;
creates a raw type Node
, without any type information available to it. You should get a warning for this line.
To remedy this, declare your head
as follows -
private Node<Item> head;
and create an instance in the following way -
head = new Node<Item>(); // if you are using jdk 6 or lesser
head = new Node<>(); // if you are using jdk 7
Update all the Node
references in a similar way, and your warnings should be gone.
If you need further clarification on type parameter bound, you can read one of my blog posts where I've tried to explain how type parameter bound works.
You need
private class Node{
...
by having it as:
private class Node<Item extends Comparable<Item>>{
you are making a new generic type called Item
that is not the same as the Item
type of the enclosing class even though it has the same name.
its simple, as you didnt specified type when you create head, node.head has type object
this should fix your problem
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;
}
}
As @JonathanDrapeau pointed out, the answer is simply: change the declaration of t
variable to Node<Item>
:
for (Node<Item> t = head.next; t != null; t = t.next){
if (gt(t.item, maxitem)){
maxitem = t.item;
}
}
The second option : remove the type argument form Node
class definition, if you want to refer to the same type as in the parent LinkedListMaxPQ
class:
public class LinkedListMaxPQ<Item extends Comparable<Item>> {
...
private class Node {
Item item;
Node next;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.