Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explanation of generic <T extends Comparable<? super T>> in collection.sort/ comparable code?

Tags:

java

generics

I use comparable interface all the time to provided natural ordering for my class through collection.sort.

Basically if I have a person class, I will get it to implement Comparable interface and will provide the implementation of compareTo. However in the definition of Collections.sort in javadocs, I see this signature

public static <T extends Comparable<? super T>> void sort(List<T> list) 

I don't understand this generics definition at all? Shouldn't it just say

<T implements Comparable<T>> 

Can someone help me with this?

like image 523
Dude Avatar asked Sep 11 '14 04:09

Dude


People also ask

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

The meaning is T implements Comparable interface! Also it means all the elements in the List<T> must implement Comparable interface, or it should be mutually comparable. All Wrapper classes, String, Date etc implements Comparable.

What does extends comparable mean in Java?

Implementing the Extends Comparable<T> Interface in Java This method compares the object with the specified object for the order. It returns a negative integer if the object is less than specified. It will return zero if the object and the specified object are equal.

What is comparable list in Java?

Java Comparable interface is used to order the objects of the user-defined class. This interface is found in java. lang package and contains only one method named compareTo(Object). It provides a single sorting sequence only, i.e., you can sort the elements on the basis of single data member only.


2 Answers

Actually, it means that T can implement Comparable<? super T>, not just Comparable<T>.

For example, it means that a Student class can implement Comparable<Person>, where Student is a subclass of Person:

public class Person {}  public class Student extends Person implements Comparable<Person> {     @Override public int compareTo(Person that) {         // ...     } } 

In this case, a List can be sorted by Collections.sort() but only based on Person's properties, because you pass the Student instance into compareTo() as a Person (unless you downcast it, of course).

In practice however, you'll never see a Student class implement Comparable<Person>. That's because Person will probably have implemented Comparable<Person>, and Student inherits it implementation. The end result is the same however: you can pass a List<Student> to Collections.sort() and have it sorted on Person's properties.

The difference between Comparable<T> and Comparable<? super T> is more obvious in the overloaded version of Collections.sort() that takes a Comparator<? super T>:

class ByAgeAscending implements Comparator<Person> {     @Override public int compare(Person a, Person b) {         return a.getAge() < b.getAge();     } }  List<Student> students = getSomeStudents(); Collections.sort(students, new ByAgeAscending()); 
like image 181
Jan Van den bosch Avatar answered Oct 11 '22 01:10

Jan Van den bosch


You always use extends with generics wildcards, even if the type parameter implements an interface.

If you look at a class that implements Comparable, you'll see that it actually (should) implement Comparable<T>, where T is the class itself.

It makes sense if you think about the type paramter passed to the Comparable interface and how it's used in the compareTo() method.

As PM 77-1 has eloquently pointed out, the super keyword allows for either the class, T, or one of its parents to implement Comparable.

like image 27
jahroy Avatar answered Oct 11 '22 02:10

jahroy