2

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.

mpnm
  • 481
  • 1
  • 7
  • 13

2 Answers2

4

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:

Slaw
  • 37,820
  • 8
  • 53
  • 80
  • Why isn't `U max(U left, U right)` in the curly brackets of the method, in your example? – mpnm Nov 05 '19 at 23:44
  • 1
    That `U` is the return type of the method. The type variable `U` is, however, declared in angle brackets which is what allows using `U` as the return type: `> U max(U left, U right)`. Or did I misunderstand your question? – Slaw Nov 05 '19 at 23:48
0

It means that T is a class type which is subtype of or inheriting Comparable which also accepts a generic type and it should be of same type as the class which is represented by T here.

E.g.

replace T by Employee class and Employee class definition is as below.

Employee is now T and Comparable's compareTo method must also accept Employee as parameter as T is now Employee per Comparable.

class Employee implements Comparable<Employee>{

    @Override
    public int compareTo(Employee o) {
        return 0;
    }
}
Vinay Prajapati
  • 7,199
  • 9
  • 45
  • 86