Tuesday, 19 February 2019

Comparable and Comparator

Comparable

Comparable implementations provide a natural ordering for a class, which allows objects of that class to be sorted automatically. 

While sorting Collections, the Collection Framework gives us an algorithm which does the natural sorting for us.
Collections.sort(l);
Lets say if we have a Collection<Name> list = new ArrayList<>() and Name does not implement Comparable, then Collections.sort(list) will throw a ClassCastException.

The sort() method provided by the Collections class is to be only used when the elements of the collection can be compared

Writing Your Own Comparable Types

The Comparable interface consists of the following method.

public interface Comparable<T> {
    public int compareTo(T o);
}

The compareTo method compares the receiving object with the specified object and returns a negative integer, 0, or a positive integer depending on whether the receiving object is less than, equal to, or greater than the specified object. If the specified object cannot be compared to the receiving object, the method throws a ClassCastException.

Points to remember when we are implementing Comparable - this will make lives easier for a developer

1. Try and make sure the Class is Immutable
2. Make sure the Constructor is checking on NPE - throw NPE sooner the better
3. Override hashcode and equals - to make sure the contract is in place
4. Override toString so that the object is printed in human readable form

Refer to this github link for demonstration
https://github.com/omerhashmininjago/java-programs/tree/master/src/main/java/com/demonstrate/concepts/collections/comparable/example1

Using Comparable interface, we can sort the elements of:
  1. String objects
  2. Wrapper class objects, for example Integer, Long etc
  3. User defined custom objects (Preferably Immutable objects)
To reverse the order of sorting, you can the method provided by the Collections class - reverseOrder(); This utility method returns a Comparator that imposes the reverse of the natural ordering on a collection of objects that implement the Comparable interface.

What if you want to sort some objects in an order other than their natural ordering? Or what if you want to sort some objects that don't implement Comparable and you dont have access to its source code?

Comparator

To do either of the above things, you'll need to provide a Comparator — an object that encapsulates an ordering. Like the Comparable interface, the Comparator interface consists of a single method.

public interface Comparator<T> {
    int compare(T o1, T o2);
}

The compare method compares its two arguments, returning a negative integer, 0, or a positive integer depending on whether the first argument is less than, equal to, or greater than the second. If either of the arguments has an inappropriate type for the Comparator, the compare method throws a ClassCastException.

Much of what was said about Comparable applies to Comparator as well. Writing a compare method is nearly identical to writing a compareTo method, except that the former gets both objects passed in as arguments. The compare method has to obey the same four technical restrictions as Comparable's compareTo method for the same reason — a Comparator must induce a total order on the objects it compares.

Please have a look at the example demonstrated on the below github link

https://github.com/omerhashmininjago/java-programs/tree/master/src/main/java/com/demonstrate/concepts/collections/comparator/example1

 Comparator Vs Comparable

The Comparable interface is a good choice when used for defining the default ordering or, in other words, if it’s the main way of comparing objects.
Then, we must ask ourselves why use a Comparator if we already have Comparable?
There are several reasons why:
  • Sometimes, we can’t modify the source code of the class whose objects we want to sort, thus making the use of Comparable impossible
  • Using Comparators allows us to avoid adding additional code to our domain classes
  • We can define multiple different comparison strategies which isn’t possible when using Comparable

No comments:

Post a Comment

Volatile keyword, Synchronized keyword and Lock interface

Volatile Marking a member variable as volatile, makes sure, when ever the member variable is accessed, its value is always read from the...