What does <T extends Comparable<T>> mean?

David Dong :

I was looking over the TheAlgorithms repository for java and came to this first: https://github.com/TheAlgorithms/Java/blob/master/Searches/SearchAlgorithm.java. I see <T extends Comparable<T>>, and I don't know what this means. I only know a little bit about generics and I know that the syntax has something to with parameter type bounds, but it would be great if someone could clarify how this has to do with Comparable<T>, and what Comparable<T> is.

There are some other questions on this forum similar to mine dealing with implementing <T extends Comparable<T>>, but the answers haven't really clarified what Comparable<T> is.

Slaw :

First, you have the Comparable interface which roughly looks like:

public interface Comparable<T> {

    int compareTo(T other);
}

As you can see, the type parameter of Comparable is used as the parameter of the compareTo method. Typically, the type argument for T is the same class which is implementing the Comparable interface. This generic setup facilitates comparing instances of the same type with each other. Here's an example:

public class Name implements Comparable<Name> {

    @Override
    public int compareTo(Name other) {
        // compute & return result
    }
}

Now let's say you have a method which should return the maximum of two objects according to their natural order. Such a method could look like the following:

public static <U extends Comparable<U>> U max(U left, U right) {
    return left.compareTo(right) >= 0 ? left : right;
}

Note: Used U as the type variable instead of T to show it is separate from the T used in the Comparable interface.

The above is a generic method. The type variable U is upper-bounded by Comparable<U>. What this means is that the type argument used in place of U must be assignable to (i.e. subtype of) Comparable<U>. For instance, if we use Name as the type argument it will work because Name is assignable to Comparable<Name>. The reason for specifying the upper-bound as Comparable<U> is that the method needs to call compareTo in order to function properly.

Name name1 = ...;
Name name2 = ...;

Name max = max(name1, name2); // U is inferred to be Name

As shown above, having U as the return type also allows assigning the result to a variable of the same type as the arguments.


Note that for maximum flexibility the max method should actually be declared like so:

public static <U extends Comparable<? super U>> U max(U left, U right) {
    return left.compareTo(right) >= 0 ? left : right;
}

The difference being the use of Comparable<? super U> as the upper-bound instead of Comparable<U>. These two Q&As should help explain why using ? super U offers greater flexibility:

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324169&siteId=1