Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics and compareTo() method

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.

like image 211
cress Avatar asked Jul 07 '15 17:07

cress


People also ask

What is compareTo method?

The compareTo() method compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The method returns 0 if the string is equal to the other string.

What are generics in Java?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.

How compareTo method is called in Java?

The Java String class compareTo() method compares the given string with the current string lexicographically. It returns a positive number, negative number, or 0. It compares strings on the basis of the Unicode value of each character in the strings.

What data type is returned from the compareTo () method?

compareTo() in java returns an integer value. It returns a positive integer if string1 is lexicographically greater than string2, negative if string2 is greater than string1, and zero if both are equal.


2 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>.

like image 88
rgettman Avatar answered Oct 05 '22 21:10

rgettman


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.

like image 20
M A Avatar answered Oct 05 '22 20:10

M A