Home » Java » Generics and compareTo() method

Generics and compareTo() method

Posted by: admin December 28, 2021 Leave a comment

Questions:

I am trying to make a SkipList and I have a method that takes a generic data type:

public void add(E key, Integer value)
{
    Node<E> p; 
    p = find(key);
}

Which takes you here:

public Node<E> find(E key)
{
    //Start at head
    Node<E> p = head;

    while (true)
    {
        while ( (p.getRight().getKey() != Node.posInf) && (p.getRight().getKey().compareTo(key) <= 0 )) 
        {
            p.setRight(p.getRight());
        }

        //More stuff down here
    }
}

The problem is on the compareTo() method. It says the compareTo() method is undefined for type E. In Eclipse it wants me to add two typecasts like this:

((String) p.getRight().getKey().compareTo((String) key) <= 0 )

Why does it want String? The data type could be anything. I tried doing typecast of E instead but Eclipse wants to change it back to String. Any help would be appreciated.

Answers:

You haven’t shown how E is defined, but the error message indicates that you didn’t place an upper bound of Comparable<E> on the declaration of E.

You can accomplish that with something like this on your class:

public class SkipList<E extends Comparable<E>>

This will allow you to call compareTo on your key variable of type E.

As to why Eclipse is suggesting casting to a String, it looks like Eclipse is guessing as to what would be the best change to make to make it compile. It may have guessed String because it’s Comparable<String>. In this case, it’s wrong, because E isn’t necessarily a String. The solution here is different, as I stated above: restrict E to be Comparable<E>.

###

The method compareTo is defined in the interface java.lang.Comparable. There is nothing in your code that tells the compiler that the type parameter E is Comparable. You can do this in the generic type declaration:

class Node<E extends Comparable<E>> {
   ...
}

By default if you don’t declare extends Comparable, you can only access methods defined in the java.lang.Object class.