Tuesday, November 29, 2011

How to override compareTo method in Java


compareTo method is on same league of equals() and hashcode() and one of the fundamental method around Java Programming and very important concept to understand in Java. I have seen in interviews that if you ask a programmer to implement equals, hashCode and CompareTo() method for a classy say Order or Employee not many succeed. Simple reason behind this is that they either not understand the concept well enough or doesn't write this stuff at all. I will try to fill that gap in this article and will see What is CompareTo(), Where to use it  and How to use it.

What is compareTo() method
--------------------------------------

compareTo in Java, override compareTo method
compareTo() method is defined in interface java.lang.Comparable and it is used to implement natural sorting on java classes. natural sorting means the the sort order which naturally applies on object e.g. lexical order for String, numeric order for Integer or Sorting employee by there ID etc. most of the java core classes including String and Integer implements CompareTo() method and provide natural sorting.


Why do you need CompareTo()
-----------------------------------------

Sorting is an essential part of application development, which you often required to implement in your system. in Java sorting is implemented using Comparator and Comparable in Java. Since we store java objects in Collection there are also certain sets and maps which provide automating sorting when you insert element on that e.g. TreeSet and TreeMap. to implement sorting you need to override either compareTo(Object o) method or Comparable class or compare(Object o1, Object o2) method of Comparator class. Most of the classes implement Comparable to implement natural order. for example if you are writing Employee object you probably want to implement Comparable interface and override compareTo() method to compare current employee with other employee based on ID. So essentially you need to override compareTo() because you need to sort elements.

How to implement compareTo in Java

Overriding CompareTo method in Java
-------------------------------------------------

There are certain rules to remember while overriding compareTo method:

1) CompareTo method must return negative number if current object is less than other object, positive number if current object is greater than other object and zero if both objects are equal to each other.

2) CompareTo must be in consistent with equals method e.g. if two objects are equal via equals() , there compareTo() must return zero otherwise if those objects are stored in SortedSet or SortedMap they will not behave properly. Since SortedSet or SortedMap use CompareTo() to check the object if two unequal object are returned equal by compareTo those will not be added into Set or Map if they are not using external Comparator.

3) CompareTo() must throw NullPointerException if current object get compared to Null object as opposed to equals() which return false on such scenario.

4) Another important point to note is don't use subtraction for comparing int values because result of subtraction can overflow as every int operation in Java is modulo 2^32. use either Integer.compareTo()  or logical operators for comparison. look Eric's comment on comment section for full explanation.


Where is CompareTo() method used
---------------------------------------------------
In Java API compareTo() method is used in SortedSet e.g. TreeSet and SortedMap e.g. TreeMap for sorting elements on natural order if no explicit Comparator is passed to Collections.sort() mehtod e.g.

List stocks = getListOfStocks();
Collections.sort(stocks);

as mentioned earlier if compareTo is not consistent with equals then it could produce strange result. let took another example you put Stock A and Stock B on StockSet which is a TreeSet. Both Stock A and Stock B are equal by equals() method but compareTo return non zero values for it which makes that StockB will also be landed into TreeSet which was voilation of Set itself because it is not supposed to allow duplicates.

Example of compareTo() in Java
--------------------------------------

Let’s see an example of how to override compareTo method in Java. This method is very similar to equals and hashcode, key thing is compareTo should provide natural ordering e.g. in this example Sorting based on Student ID.


  public class Student implements Comparable {
    private int id;
    private String name;
    private int age;
  
    /*
      Compare a given Student with current(this) object.
      If current Student id is greater than the received object,
      then current object is greater than the other.
   */
    
    public int compareTo(Student otherStudent) {
       // return this.id - otherStudent.id ; //result of this operation can overflow
           return (this.id < otherStudent.id ) ? -1: (this.id > otherStudent.id) ? 1:0 ;
    }
  
}


That’s all on implementing compareTo method in Java. Please add any other fact which you think important to note while overriding compareTo. In Summary compareTo should provide natural ordering and compareTo must be consistent with equals() method in Java.

No comments:

Post a Comment

Thank you for your comment