Monday, 21 April 2014

Comparable and Comparator Explained Novicely!!!!

First things first...we all know what both interfaces of java.lang and util package do...but we are confused whats the difference and when to use what?

Primary advantage of Comparable over Comparator in Java is If any class implement Comparable interface in Java then collection of that object either List or Array can be sorted automatically by using Collections.sort() or Array.sort() method and object will be sorted based on there natural order defined by CompareTo method.
This is worth noticing( defined by CompareTo method.)
But comparator has big advantage. Every time you want to add more attributes for sorting they are added as separate classes whereas in case of Comparable, you need to modify the same compareTO method. So my recommendation is, always let your class implement the Comparable interface for primary key attribute based sorting because that rarely changes, for non-key attributes sorting use comparator as you can add and remove them very easily.

Lets take example of Employee class with attributes of Id,Name,DOJ
In case of Comparable the Employee class has to implement the Comparable interface to define its natural ordering based on either Id,Name or DOJ



public class Employee implements Comparable<employee>{

@Override 
    public int compareTo(Object o) {
        Employee p = (Employee) o; 
        return this.id - o.id ;
        //OR return this.getName().compareTo(e.getName());
    }

But in case of Comparator You create a separate class which implements the Comparator interface and implement the compare method which does the actual work.
compare(Object e1, Object e2) we do not touch Employee class at all means don't let it implement either Comparable or Comparator class. You create your comparators, Here we create two comparators one for Name and other for date of joining. EmployeeNameComparator, EmployeeDOJComparator which implement the comparator interface.
We call the sort method from our main() class like:
Collections.sort(list,new EmployeeNameComparator());
Collections.sort(list,new EmployeeDOJComparator());
Following are some classes in Java which implement comparable interface:
Note:
ClassNatural Ordering that the class has
Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimalSigned numerical
CharacterUnsigned numerical
BooleanBoolean.True > Boolean.False
StringLexographic
DateChronological
FileSystem-dependent lexicographic path name
CollationKeyLocale-specific lexicographic
Other classes implementing Comparable interface are URI, Charset, ByteBuffer, ShortBuffer, CharBuffer, IntBuffer, FloatBuffer, DoubleBuffer, LongBuffer

Here all the API classes have implemented Comparable as that is its natural ordering .

Comparator vs Comparable

Parameter
Comparable
Comparator
Sorting logic
Sorting logic must be in same class whose objects are being sorted. Hence this is called natural ordering of objects
Sorting logic is in separate class. Hence we can write different sorting based on different attributes of objects to be sorted. E.g. Sorting using id,name etc.
Implementation

Class whose objects to be sorted must implement this interface.e.g Country class needs to implement comparable to collection of country object by id
Class whose objects to be sorted do not need to implement this interface.Some other class can implement this interface. E.g.-CountrySortByIdComparator class can implement Comparator interface to sort collection of country object by id
Sorting method
int compareTo(Object o1)
This method compares this object with o1 object and returns  a integer.Its value has following meaning
1. positive – this object is greater than o1
2. zero – this object equals to o1
3. negative – this object is less than o1
int compare(Object o1,Object o2)
This method compares o1 and o2 objects. and returns  a integer.Its value has following meaning.
1. positive – o1 is greater than o2
2. zero – o1 equals to o2
3. negative – o1 is less than o1
Calling method
Collections.sort(List)
Here objects will be sorted on the basis of CompareTo method
Collections.sort(List, Comparator)
Here objects will be sorted on the basis of Compare method in Comparator
Package
Java.lang.Comparable

Java.util.Comparator


Sorting Objects by their Natural Order

To sort a List you do this:
List list = new ArrayList();

//add elements to the list

Collections.sort(list);
When sorting a list like this the elements are ordered according to their "natural order". For objects to have a natural order they must implement the interface java.lang.Comparable. In other words, the objects must be comparable to determine their order. Here is how the Comparable interface looks:
public interface Comparable<T> {
  int compareTo(T o);
}
The compareTo() method should compare this object to another object, return an int value. Here are the rules for thatint value:
  • Return a negative value if this object is smaller than the other object
  • Return 0 (zero) if this object is equal to the other object.
  • Return a positive value if this object is larger than the other object.
There are a few more specific rules to obey in the implementation, but the above is the primary requirements. Check out the JavaDoc for the details.
Let's say you are sorting a List of String elements. To sort them, each string is compared to the others according to some sorting algorithm (not interesting here). Each string compares itself to another string by alphabetic comparison. So, if a string is less than another string by alphabetic comparison it will return a negative number from the compareTo()method.
When you implement the compareTo() method in your own classes you will have to decide how these objects should be compared to each other. For instance, Employee objects can be compared by their first name, last name, salary, start year or whatever else you think makes sense.

Sorting Objects Using a Comparator

Sometimes you may want to sort a list according to another order than their natural order. Perhaps the objects you are sorting do not even have a natural order. In that case you can use a Comparator instead. Here is how you sort a list using a Comparator:
List list = new ArrayList();

//add elements to the list

Comparator comparator = new SomeComparator();

Collections.sort(list, comparator);
Notice how the Collections.sort() method now takes a java.util.Comparator as parameter in addition to the List. This Comparator compares the elements in the list two by two. Here is how the Comparator interface looks:
public interface Comparator<T> {
    int compare(T object1, T object2);
}
The compare() method compares two objects to each other and should:
  • Return a negative value if object1 is smaller than object2
  • Return 0 (zero) if objec1 is equal to object2.
  • Return a positive value if object1 is larger than object2.
There are a few more requirements to the implementation of the compare() method, but these are the primary requirements. Check out the JavaDoc for more specific details.
Here is an example Comparator that compares two fictive Employee objects:
public class MyComparator<Employee> implements Comparator<Employee> {

    public int compare(Employee emp1, Employee emp2){
       if(emp1.getSalary() <  emp2.getSalary()) return -1;
       if(emp1.getSalary() == emp2.getSalary()) return 0;
       return 1;
    }
}
A shorter way to write the comparison would be like this:
public class MyComparator<Employee> implements Comparator<Employee> {

    public int compare(Employee emp1, Employee emp2){
       return emp1.getSalary() - emp2.getSalary();
    }
}
By subtracting one salary from the other, the resulting value is automatically either negative, 0 or positive. Smart, right?
If you want to compare objects by more than one factor, start by comparing by the first factor (e.g first name). Then, if the first factors are equal, compare by the second factor (e.g. last name, or salary) etc.



inputs from:
http://java-espresso.blogspot.in/2011/06/comparable-and-comparator-interfaces.html
http://tutorials.jenkov.com/java-collections/sorting.html

No comments:

Post a Comment