How to use Comparator and Comparable in Java? With example (original) (raw)

Comparator and Comparable in Java Examples

The difference between Comparator and Comparable in Java is very popular Java interview question mostly asked in the telephonic rounds and writing code to sort objects using Comparable or Comparator is popular on the written test round of interviews. The question was this “How you will sort Employee object based on his EmployeeID and his name” and this involves the use of both Comparable as well as Comparator interface in Java. This post is my revision on Java fundamentals similar to what I did about the equals method in Java and some tips to override hashCode in Java.

All of these methods are fundamentals in the Java programming language and correct understanding is a must for any Java developer. Comparators and comparable in Java are two interfaces that are used to implement sorting in Java.

It’s often required to sort objects stored in any collection classes like ArrayList, HashSet, or in Array, and at that time we need to use either compare() or compareTo() method defined in java.util.Comparator and java.lang.Comparable.

In this Java tutorial, we will see examples of Comparator and Comparable to sort objects in Java and discuss some best practices around when to use Comparator interface, etc. Any way before moving ahead Let’s see some important differences between Comparable and Comparator in Java.

Comparator vs Comparable in Java

Difference between Comparator vs Comparable in JavaHere are some of the common differences, which is worth remembering to answer this question if asked during a telephonic or face to face interview:

  1. Comparator in Java is defined in java.util package while Comparable interface in Java is defined in java.lang package, which very much says that Comparator should be used as a utility to sort objects which Comparable should be provided by default.

  2. Comparator interface in Java has method public int compare (Object o1, Object o2) which returns a negative integer, zero or a positive integer as the first argument is less than, equal to, or greater than the second. While Comparable interface has method public int compareTo(Object o) which returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.

  3. If you see the logical difference between these two is Comparator in Java compare two objects provided to him, while Comparable interface compares "this" reference with the object specified. I have shared a lot of tips on how to override compareTo() method and avoid some common mistakes programmer makes while implementing Comparable interface.

  4. Comparable in Java is used to implement the natural ordering of objects. In Java API String, Date and wrapper classes implement a Comparable interface.Its always good practice to override compareTo() for value objects.

  5. If any class implements Comparable interface in Java then collection of that object either List or Array can be sorted automatically by using Collections.sort() or Arrays.sort() method and object will be sorted based on there natural order defined by CompareTo method.

6)Objects which implement Comparable in Java can be used as keys in a SortedMap like TreeMap or elements in a SortedSet for example TreeSet, without specifying any Comparator.

These were combination of some theoretical and practical differences between Comparator and Comparator interface in Java. It does help you to decide when to use Comparator vs Comparable but things will be more clear when we some best practices around using both of these interfaces. Now let’s see an example of Comparator in Java:

Example of using Comparator and Comparable in Java

So in summary, if you want to sort objects based on natural order then use Comparable in Java and if you want to sort on some other attribute of an object then use Comparator in Java. Now to understand these concepts lets see an example or real-life coding:

  1. There is a class called Person, sort the Person based on person_id, which is primary key in the database

  2. Sort the Person based on there name.

For a Person class, sorting based on person_id can be treated as natural order sorting and sorting based on name field can be implemented using Comparator interface. To sort based on person_id we need to implement compareTo() method.

public class Person implements Comparable {
private int person_id;
private String name;

/**
* Compare current person with specified person
* return zero if person_id for both person is same
* return negative if current person_id is less than specified one
* return positive if specified person_id is greater than specified one
*/

@Override
public int compareTo(Object o) {
Person p = (Person) o;
return this.person_id - o.person_id ;
}
….
}

Generally, you should not use the difference of integers to decide output of compareTo method as result of integer subtraction can overflow but if you are sure that both operands are positive then its one of the quickest way to compare two objects. See my post things to remember while overriding compareTo in Java for more tips on compareTo.

And for sorting based on person name we can implement compare(Object o1, Object o2) method of Java Comparator class.

/**
* Comparator implementation which sorts Person objects on person_id field
*/
public class SortByPerson_ID implements Comparator{

public int compare(Object o1, Object o2) {

Person p1 = (Person) o;
Person p2 = (Person) o;
return p1.getPersonId() - p2.getPersonId();
}
}

Similar guidelines applies while implementing compare() method as well and instead of using subtraction operator, its better to use logical operator to compare whether two integers are equal to, less than or greater than. You can write several types of Java Comparator based upon your need for example reverseComparator , ANDComparator , ORComparator etc which will return negative or positive number based upon logical results. String in Java even provides an special comparator called CASE_INSENSITIVE_ORDER, to perform case insensitive comparison of String objects.

How to Compare String in Java

String is immutable in Java and one of the most used value class. For comparing String in Java we should not be worrying because String implements Comparable interface and provides a lexicographic implementation for CompareTo method which compare two strings based on contents of characters or you can say in lexical order. You just need to call String.compareTo(AnotherString) and Java will determine whether specified String is greater than , equal to or less than current object. See my post 4 example to compare String in Java for alternatives ways of comparing String.

How to Compare Dates in Java

Dates are represented by java.util.Date class in Java and like String, Date also implements Comparable in Java so they will be automatically sorted based on their natural ordering if they got stored in any sorted collection like TreeSet or TreeMap. If you explicitly want to compare two dates in Java you can call Date.compareTo(AnotherDate) method in Java and it will tell whether the specified date is greater than , equal to or less than current String. See my post 3 ways to compare Dates in Java for more alternatives of comparing two dates.

When to use Comparator and Comparable in Java

At last let’s see some best practices and recommendation on when to use Comparator or Comparable in Java:

  1. If there is a natural or default way of sorting Object already exist during the development of Class then use Comparable. This is intuitive and you are given the class name people should be able to guess it correctly like Strings are sorted chronically, Employee can be sorted by their Id etc.

On the other hand, if an Object can be sorted on multiple ways and client is specifying on which parameter sorting should take place then use the Comparator interface. for example, Employee can again be sorted on name, salary or department and clients needs an API to do that. Comparator implementation can sort out this problem.

  1. Some time you write code to sort objects of a class for which you are not the original author, or you don't have access to code. In these cases you can not implement Comparable and Comparator is only way to sort those objects.

  2. Beware with the fact that How those objects will behave if stored in SorteSet or SortedMap like TreeSet and TreeMap. If an object doesn't implement Comparable then while putting them into SortedMap, always provided a corresponding Comparator which can provide sorting logic.

  3. Order of comparison is very important while implementing the Comparable or Comparator interface. for example, if you are sorting objects based upon name then you can compare first name or last name on any order, so decide it judiciously. I have shared more detailed tips on compareTo in my post on how to implement CompareTo in Java.

  4. Comparator has a distinct advantage of being self-descriptive for example if you are writing Comparator to compare two Employees based upon their salary then a name that comparator as SalaryComparator, on the other hand, compareTo()

Related Java Tutorial from Javarevisited Blog