Java Comparator and Comparable demystified

45 Flares Twitter 7 Facebook 4 Google+ 34 LinkedIn 0 Filament.io 45 Flares ×

Java comparator and java comparable both achieve the same thing, helps to sort objects and both are Interfaces. Let us first explore comparable ( java.lang.comparable) and then comparator ( java.util.Comparator ).

Comparable

Quick facts: Belongs to java.lang  package and has a single method int compareTo(T o).  The compareTo method is referred to as the natural comparison method. The comparable interface and its compareTo method is used to ensure the natural ordering of  objects in a collection. Many java objects, by default implements this interface and thereby this method. For instance , java.lang.Integer class implements Comparable and compareTo method. That is why when we sort a collection of  Integer objects, we get the results properly sorted.  Few of the famous java classes that implements this interface are String, Integer, Float, Double, Boolean and Date. Now you know why you get the results sorted when any of these are added in a collection and you call sort.

To explain this let us add a set of integers to a  List.

package com.javahash.sample;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComparatorTest {

/**
* @param args
*/
public static void main(String[] args) {

testComparable();
}

public static void testComparable(){
  List integerList=new ArrayList();
  integerList.add(new Integer(10));
  integerList.add(new Integer(9));
  integerList.add(new Integer(12));
  integerList.add(new Integer(6));
  integerList.add(new Integer(7));
  //Sorts the List, based on the default implementation
  //provided by the Integer class
  Collections.sort(integerList);
  printElements(integerList);

}

public static void printElements(List integerList){
 for(int i:integerList){
	System.out.println(i);
  }
 }
}

When we execute this code we get the output as

6
7
9
10
12

Properly sorted in the ascending order. This is because the integer Object’s compareTo method provides the implementation in the ascending order and Collections.sort() method uses this implementation to sort the objects.

Good, now what if for some special scenario, we want to sort results in the descending order. Quick and easy method is to sub class the java.lang.Integer class and provide a new implementation for compareTo. But …. Hold on, what are you saying. This doesn’t sound right. Yes, you are correct, we cannot subclass a java.lang.Integer since it is declared final and in any case that is a bad idea since some other part of our program may rely on the natural sorting order provided by the Integer class.

Stuck, what is the way forward. This is where the Java Comparator interface comes to our rescue.  Let us write a Java  Comparator that sorts the Integers in the descending order.

Comparator

class IntegerDescendingSorter implements Comparator {

	@Override
	public int compare(Integer arg1, Integer arg2) {

	  if(arg1 < arg2 ){                      return 1;                            }else if(arg1 > arg2){
	    return -1;
	 }
	return 0;
   }
}

Let us understand the workings of the compare Method. It is confusing for many to understand the workings of compare. Let me try to explain this in a simpler way. The first argument (arg1) is the first object and the second argument (arg2) is the second object. Pretty straight forward.

Condition for Sorting in the Ascending Order

If the first element is less than the second element, return a negative number. If the first element is greater than the second element, return a positive number. If both are equal return 0. This is the condition for sorting in the ascending order.

Condition for Sorting in the Descending Order

If we reverse the above logic, that is we return a positive number when first number is less than the second number and return a negative number if the first number is greater than the second, we can sort in the descending order.

Hope this is clearer. The above code ( IntegerDescendingSorter ) implements this logic to Sort in the Descending order.

Let us complete this with the full code

package com.javahash.sample;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComparatorTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

    	   testComparable();
	}

	public static void testComparable(){

	 List integerList=new ArrayList();
	 integerList.add(new Integer(10));
	 integerList.add(new Integer(9));
	 integerList.add(new Integer(12));
	 integerList.add(new Integer(6));
	 integerList.add(new Integer(7));
	Collections.sort(integerList, new IntegerDescendingSorter());
	printElements(integerList);
    }
   public static void printElements(List integerList){
    for(int i:integerList){
	System.out.println(i);
    }
  }
}

class IntegerDescendingSorter implements Comparator {

	@Override
	public int compare(Integer arg1, Integer arg2) {
		if(arg1 < arg2 ){ 			                    return 1; 		                 }else if(arg1 > arg2){
		   return -1;
		}
		return 0;
	}
 }

We used the Collections.sort() method that takes an extra parameter, the Comparator, public static void sort(List list, Comparator<? super T> c)

To this sort method, we pass our Comparator implementation. The Collections.sort method will use our Comparator and its implementation of compare method to sort the objects. If we don’t provide the Comparator the elements will be sorted based on the natural ordering as implemented by the compareTo method of the Comparable interface.

Hope now you know when to you need to write a Comparator.

Sorting Custom Objects

We have seen the above example using the Built-in Java.lang.Integer class. What if we want to sort a custom object. Let us consider a User object that holds the user name,date of birth and home town. If we don’t implement the Comparable interface, we cannot Sort this object using the default Collections.sort method that takes a List. If we try, the compiler will throw a compiler error informing us that this custom object doesn’t implement the Comparable interface. We need to implement the Comparable interface and provide a proper implementation of compareTo method for this to work. Let us consider that the natural sorting we want is to sort the users by their Id. In this case we just need to provide that implementation in the compareTo method. This is the natural sorting and if for some situations we need to sort by say their home town, we can write our custom Compartor to achieve this.

Share this post:

Related Posts

  • chandiprasad

    Excellent Explanation !! Simply superb ! Thanks

  • Kishore

    Seriously, you are a pro……thank u buddy…..

  • user

    looks like needs to correct below phrase..

    If we reverse the above logic, that is we return a positive number when first number is less than the second number and return a negative number if the first number is greater than the first, we can sort in the descending order.

    with …

    If we reverse the above logic, that is we return a positive number when first number is less than the second number and return a negative number if the first number is greater than the second, we can sort in the descending order.

    • http://pickadvice.com/ prem kumar

      That was a typing error.Thanks for pointing out the mistake.I have made the correction.

  • Tarun Jain

    thanks , you explained it much simpler then X, Y stuff of java documentation. :)

  • nagaraj L M

    Sorting logic is in separate class. Hence we can write different sorting based on different attributes of objects to be sorted.Is this mean applying differant sorting methods like bubble,quick etc sorts ?