implementing compareTo() with generics and collection

madhur picture madhur · Sep 2, 2012 · Viewed 9.9k times · Source

i m working with collections and i cant figure this out... I want to override compareTO() method based on the "data" variable in the Node class.. so that i can invoke collection.sort() to sort the arraylist..

public class Node<E> implements Comparable<E>{

    public E data;
    public Node<E> next;

    public Node(){
        data=null;
        next=null;
    }

    public Node(E data1){
        data=data1;
    }

    public E getData(){
        return data;        
    }

    public Node<E> getNext(){
        return next;        
    }

    @Override
    public int compareTo(E o) {
        // TODO Auto-generated method stub
        return 0;
    }
}

And

public class Test { 
    public static void main(String args[]){
        ArrayList<Node> arr= new ArrayList<Node>();
        Node n1=new Node(1);
        Node n2=new Node(3);
        Node n3=new Node(4);
        Node n4=new Node(3);
        Node n5=new Node(6);
        Node n6=new Node(2);
        arr.add(n1);
        arr.add(n2);
        arr.add(n3);
        arr.add(n4);
        arr.add(n5);
        arr.add(n6);

        Collections.sort(arr);  
    }
}

Answer

Jon Skeet picture Jon Skeet · Sep 2, 2012

Your declaration looks odd to me. It would be odd to compare a Node<Integer> with an Integer for example - it would make more sense to compare a Node<Integer> with another Node<Integer> by comparing the integers within them.

You then need to constrain E such that you can compare the two data values.

So I suspect want:

public class Node<E extends Comparable<E>> implements Comparable<Node<E>> {
    ...
    public int compareTo(Node<E> node) {
        return data.compareTo(node.data);
    }
}

You could make this slightly more flexible at the cost of complexity, like this:

public class Node<E extends Comparable<? super E>> implements Comparable<Node<E>>

(The body of the code would remain the same...)