Difference between Comparable and Comparator Interface along with Example In Java : Collection

Difference between Comparable and Comparator with example is probably one of the most important question on java collections topic ,which are  mostly used in Java as the sorting tools for the Collection classes such as the Arraylist ,Hashset ,etc.

 First we need to understand what are comparable and comparator interfaces .

Read Also :    Difference between  ArrayList and Vector

What is Comparable Interface ? Where we use it ?

Comparable Interface : Comparable is an public interfaces which is used to impose an natural ordering (if numbers then 1,2,3 or in alphabetical order   'a','b','c' ) of the class that implements it.
Now here the total ordering defines as the natural ordering which means in JVM that when we compare two objects using the comparable interfaces they are actually compared through their ASCII values which is the natural ordering. This means that the comparable by default uses the sorting technique of JVM i.e.  Of sorting by the ASCII values.Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections.sort (and Arrays.sort).

What is Comparator Interface ? Where we use it ?

Comparator Interface : A comparison function, which is used to impose ordering on some collection of objects. To allow precisely control over the sort order , Comparators can be passed to a sort method (e.g Collections.sort()). Certain type of data structures such as TreeSet or TreeMap can also be sorted using Comparator.

Read Also :     How Hash Map works in Java


Differences between the Comparator and the Comparable interfaces :

1.  Sort sequence :  In comparable ,Only one sort sequence can be created while in comparator many sort sequences can be   created .



2.  Methods Used : 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.  Objects needed for Comparision : If you see then logical difference between these two is Comparator in Java compare two objects provided to it , while Comparable interface compares "this" reference with the object specified. So only one object is provided which is then compared to "this" reference.

4 Modify Classes :One has to modify the class whose instances you want to sort while in comparator one build a class separate from the class whose instances one want to sort .

5. Package : 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 an utility to sort objects which Comparable should be provided by default.



Points to Remember regarding Comparable and Comparator :

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

2. 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 Arrays.sort() method and object will be sorted based on there natural order defined by CompareTo method.

3. 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.


Read Also :   Difference between Iterator and Enumeration with example


Before Moving onto the examples of Comparable and Comparator we need to learn more about the few important functions

Functions with the Comparable Interface :

Often, it is not enough to simply know whether two strings are identical. For sorting applications, you need to know which is less than, equal to, or greater than the next. A string is less than another if it comes before the other in dictionary order. A string is greater than another if it comes after the other in dictionary order. The String method compareTo( ) serves this purpose. It has this general form:

1) public int compareTo(Object o) :

Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the  specified object .

Here , str is the String being compared with the invoking String. The result of the comparison is returned and is interpreted as shown here:

Value                                    Meaning

Less than zero                     The invoking string is less .

Greater than zero                The invoking string is greater .

Zero                                    The two strings are equal.



Functions with the Comparator Interface :

1) public int compare (Object o1,Object o2)

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

     2) public boolean equals(Object obj)

Indicates whether some other object is "equal to" this Comparator. This method must obey the general contract of Object.equals(Object). Additionally, this method can return true only if the specified Object is also a comparator and it imposes the same ordering as this comparator. Thus, comp1.equals(comp2) implies that sgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1, o2)) for every object reference o1 and o2 .



Example of Comparable Interface :


Comparable interface:

Class whose objects to be sorted must implement this interface.In this,we have to implement compareTo(Object) method.

For example:


Country.java

//If this.countryId < country.countryId:then compare method will return -1
//If this.countryId > country.countryId:then compare method will return 1
//If this.countryId==country.countryId:then compare method will return 0

public class Country implements Comparable<Country>{
    int countryId;
    String countryName;
    
    
    public Country(int countryId, String countryName) {
        super();
        this.countryId = countryId;
        this.countryName = countryName;
    }
    
    @Override
    public int compareTo(Country country) {
        return (this.countryId < country.countryId ) ? -1: (this.countryId > country.countryId ) ? 1:0 ;
    }
    
    
    public int getCountryId() {
        return countryId;
    }
    
    
    public void setCountryId(int countryId) {
        this.countryId = countryId;
    }
    
    
    public String getCountryName() {
        return countryName;
    }
    
    
    public void setCountryName(String countryName) {
        this.countryName = countryName;
    }
    
}


ComparableMain.java


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

public class ComparableMain {
    
    public static void main(String[] args) {
        Country indiaCountry=new Country(1, "India");
        Country chinaCountry=new Country(4, "USA");
        Country nepalCountry=new Country(3, "Russia");
        Country bhutanCountry=new Country(2, "Japan");
        
        List<Country> listOfCountries = new ArrayList<Country>();
        listOfCountries.add(indiaCountry);
        listOfCountries.add(usaCountry);
        listOfCountries.add(russiaCountry);
        listOfCountries.add(japanCountry);
        
        System.out.println("Before Sort  : ");
        for (int i = 0; i < listOfCountries.size(); i++) {
            Country country=(Country) listOfCountries.get(i);
            System.out.println("Country Id: "+country.getCountryId()+"||"+"Country name:"+country.getCountryName());
        }
        Collections.sort(listOfCountries);
        
        System.out.println("After Sort  : ");
        for (int i = 0; i < listOfCountries.size(); i++) {
            Country country=(Country) listOfCountries.get(i);
            System.out.println("Country Id: "+country.getCountryId()+"|| "+"Country name: "+country.getCountryName());
        }
    }
    
}


OUTPUT :  India,Japan,Russia,USA


Example of Comparator Interface:


We will create class country having attribute id and name and will create another class CountrySortByIdComparator which will implement Comparator interface and implement compare method to sort collection of country object by id and we will also see how to use anonymous comparator.

Country.java

public class Country{
    int countryId;
    String countryName;
    
    public Country(int countryId, String countryName) {
        super();
        this.countryId = countryId;
        this.countryName = countryName;
    }
    
    public int getCountryId() {
        return countryId;
    }
    
    
    public void setCountryId(int countryId) {
        this.countryId = countryId;
    }
    
    
    public String getCountryName() {
        return countryName;
    }
    
    
    public void setCountryName(String countryName) {
        this.countryName = countryName;
    }
    
}


CountrySortbyIdComparator.java

import java.util.Comparator;

//If country1.getCountryId() < country2.getCountryId():then compare method will return -1
//If country1.getCountryId() > country2.getCountryId():then compare method will return 1
//If country1.getCountryId()==country2.getCountryId():then compare method will return 0

public class CountrySortByIdComparator implements Comparator<Country>{
    
    @Override
    public int compare(Country country1, Country country2) {
        
        return (country1.getCountryId() < country2.getCountryId() ) ? -1: (country1.getCountryId() > country2.getCountryId() ) ? 1:0 ;
    }
    
}

ComparatorMain.java

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

public class ComparatorMain {
    
    public static void main(String[] args) {
        Country indiaCountry=new Country(1, "India");
        Country chinaCountry=new Country(3, "USA");
        Country nepalCountry=new Country(4, "Russia");
        Country bhutanCountry=new Country(2, "Japan");
        
        List<Country> listOfCountries = new ArrayList<Country>();
        listOfCountries.add(indiaCountry);
        listOfCountries.add(usaCountry);
        listOfCountries.add(russiaCountry);
        listOfCountries.add(japanCountry);
        
        System.out.println("Before Sort by id : ");
        for (int i = 0; i < listOfCountries.size(); i++) {
            Country country=(Country) listOfCountries.get(i);
            System.out.println("Country Id: "+country.getCountryId()+"||"+"Country name: "+country.getCountryName());
        }
        Collections.sort(listOfCountries,new CountrySortByIdComparator());
        
        System.out.println("After Sort by id: ");
        for (int i = 0; i < listOfCountries.size(); i++) {
            Country country=(Country) listOfCountries.get(i);
            System.out.println("Country Id: "+country.getCountryId()+"|| "+"Country name: "+country.getCountryName());
        }
        
        //Sort by countryName
        Collections.sort(listOfCountries,new Comparator<Country>() {
            
            @Override
            public int compare(Country o1, Country o2) {
                return o1.getCountryName().compareTo(o2.getCountryName());
            }
        });
        
        System.out.println("After Sort by name: ");
        for (int i = 0; i < listOfCountries.size(); i++) {
            Country country=(Country) listOfCountries.get(i);
            System.out.println("Country Id: "+country.getCountryId()+"|| "+"Country name: "+country.getCountryName());
        }
    }
    
}

OUTPUT :  India,Japan,USA,Russia    // sort according to id


 Functional Java 8 Use of Comparator

difference between comparable and comparator
                        Image source : http://www.slideshare.net/andreaiacono/java8-39841939

Situations when to use Comparable and Comparator

1. If there is a natural or default way of sorting Object already exist during development of Class than use Comparable. This is intuitive and you given the class name people should be able to guess it correctly like Strings are sorted chronically, Employee can be sorted by there 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 than use 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.

2. Some time you write code to sort object 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.

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

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

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

Note :

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 object then use Comparator in Java.






If you still have any doubt regarding the difference between comparator and comparable then please write in comments



About The Author

Subham Mittal has worked in Oracle for 3 years .
For more java articles ,Click here to Subscribe JavaHungry