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?
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.
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.
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.
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());
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With