I'm new here and this is my first post. I've just completed my Java OCA and now moving onto studying for the OCP. I have a question regarding Comparable interface.
I have this code snippet which explains how Comparable is implemented:
import java.util.*;
public class Duck implements Comparable<Duck> {
private String name;
public Duck(String name) {
this.name = name;
}
public String toString() { // use readable output
return name;
}
public int compareTo(Duck d) {
return name.compareTo(d.name); // call String's compareTo
}
public static void main(String[] args) {
List<Duck> ducks = new ArrayList<>();
ducks.add(new Duck("Quack"));
ducks.add(new Duck("Puddles"));
Collections.sort(ducks); // sort by name
System.out.println(ducks); // [Puddles, Quack]
}
}
I more or less understand what is goin on here but below this code snippet the author quotes that:
The Duck class implements the Comparable interface. Without implementing that interface, all we have is a method named compareTo(), but it wouldn't be a Comparable object.
My question is why would it not be comparable? Is this something to do with the fact that calling code such as the Collections.sort()
would internally use the Comparable type as a reference parameter to compare any object?
Thanks in advance for any help and I hope my question makes sense.
Java is a Object Oriented Based language. Which supports inheritance through classes/ polymorphism through class/abstract class/interface
interface Comparable<T> {
// methods
}
class Person implements Comparable<Person> {
//methods
}
This essentially means any object of the Type Person is also of the Comparable Type.
interface Runnable {}
class Task implements Runnable {}
this means any object created of Task class is also of the Runnable Type.
This is what the author means.
If you do not implement Comparable interface, yet define the compareTo() method, you are just defining a method inside the class, as any other method. YOU ARE NOT OVERRIDING THE compareTo() method in the Comparable interface defined.
You can still compare each object using your compareTo() method, but you need to define your own sort method which internally would call compareTo() method to get the list in a sorted way.
The Java API Collections.sort() internally converts the list to an Object[] and calls the Arrays.sort(). Now Arrays.sort() will use a modified version of the TimSort Algorithm for sorting and the contract is - it does the sorting of elements of the Array only if they are of the Comparable Type.
You can check, for all of the internal calls, it states clearly :
@throws IllegalArgumentException (optional) if the comparator is found to violate the {@link Comparator} contract
So to pass any Object Types to the sort() it has to be also of the type Comparable. Strings/Wrappers are already of the Comparable Type. Hence you need to take care of this contract while defining your user defined objects.
"Without implementing that interface, all we have is a method named compareTo(), but it wouldn't be a Comparable object."
-Simply put, it means without implementing the interface, you have a Duck type object, NOT comparable type