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
Here all the API classes have implemented Comparable as that is its natural ordering .
inputs from:
http://java-espresso.blogspot.in/2011/06/comparable-and-comparator-interfaces.html
http://tutorials.jenkov.com/java-collections/sorting.html
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:
Other classes implementing Comparable interface are URI, Charset, ByteBuffer, ShortBuffer, CharBuffer, IntBuffer, FloatBuffer, DoubleBuffer, LongBuffer
Note:
Class | Natural Ordering that the class has |
---|---|
Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal | Signed numerical |
Character | Unsigned numerical |
Boolean | Boolean.True > Boolean.False |
String | Lexographic |
Date | Chronological |
File | System-dependent lexicographic path name |
CollationKey | Locale-specific lexicographic |
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 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
| |
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