简体   繁体   中英

need for casting to a generic type in java

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM