Comparable and Comparator Interface in Java

Comparable and Comparator in Java: When we perform some operation at some time, we need sorting. As we have in our previous post, Java programming language provides some inbuilt methods to sort the primitive data types like array or wrapper classes array or list.

Before learning how to use Comparable and Comparator in Java, let’s rewind and learn how we can sort the array/list primitive types and wrapper class. We try to learn the uses of Comparable and Comparator in Java.

package com.journaldev.sort;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class JavaObjectSorting 
{
   /**
    * This class shows how to sort primitive arrays,
    * Wrapper classes Object Arrays
    * @param args
    */
   public static void main(String[] args) 
   {
      //sort primitives array like int array
      int[] intArr = {5,9,1,10};
      Arrays.sort(intArr);
      System.out.println(Arrays.toString(intArr));
      //sorting String array
      String[] strArr = {"A", "C", "B", "Z", "E"};
      Arrays.sort(strArr);
      System.out.println(Arrays.toString(strArr));
      //sorting list of objects of Wrapper classes
      List<String> strList = new ArrayList<String>();
      strList.add("A");
      strList.add("C");
      strList.add("B");
      strList.add("Z");
      strList.add("E");
      Collections.sort(strList);
      for(String str: strList) System.out.print(" "+str);
   }
}

The above example shows how easy it is to sort an Array and list object simply by calling Arrays.sort() and Collections.sort(). But in the same way, we can not use the objects of custom classes. To do that, we need to implement the Comparable interface in your custom class and need to implement the abstract method, which is present inside the comparable interface.

public abstract int compareTo(T obj)

The comparable interface has only one abstract method mentioned above, so according to the abstract class rule, we need to implement the abstract method in our class; otherwise, we need to declare our class as abstract.

Java provides two interfaces to sort the custom class objects:

  • Comparable
  • Comparator

Using Comparable Interface

This comparable object can compare itself with other objects, but the class must implement java.lang.Comparable interface to compare its instance. For the sorting, you must override the comparable interface’s compareTo ().

// A Java program to demonstrate use of Comparable
import java.io.*;
import java.util.*;

// A class 'Movie' that implements Comparable
class Movie implements Comparable<Movie>
{
   private double rating;
   private String name;
   private int year;

   // Used to sort movies by year
   public int compareTo(Movie m)
   {
      return this.year - m.year;
   }

   // Constructor
   public Movie(String nm, double rt, int yr)
   {
      this.name = nm;
      this.rating = rt;
      this.year = yr;
   }

   // Getter methods for accessing private data
   public double getRating() { return rating; }
   public String getName() { return name; }
   public int getYear() { return year; }
}

// Driver class
class Main
{
   public static void main(String[] args)
   {
      ArrayList<Movie> list = new ArrayList<Movie>();
      list.add(new Movie("Force Awakens", 8.3, 2015));
      list.add(new Movie("Star Wars", 8.7, 1977));
      list.add(new Movie("Empire Strikes Back", 8.8, 1980));
      list.add(new Movie("Return of the Jedi", 8.4, 1983));

      Collections.sort(list);

      System.out.println("Movies after sorting : ");
      for (Movie movie: list)
      {
         System.out.println(movie.getName() + " " +
               movie.getRating() + " " +
               movie.getYear());
      }
   }
}

When we try to sort custom class objects with comparable help, we can use only one attribute for sorting, but if you try to sort with multiple attributes, you have to use the Comparator.

Note: When you try to use comparable, you have to use the base class

Using Comparator

When we are sorting a custom class object using comparable, we are using the same class, and we can also use one attribute for sorting. So, because of those problems, a Comparator is introduced, in which we can make a separate class for each attribute and use the Comparator interface. The compareTo() method is incomparable in the comparator, and we need to override the compare() method.

The comparator class object is capable of comparing two objects of different classes. The syntax of compare methods is

public int compare(Object obj1, Object obj2):

This interface is present in java.util package, and it has two methods in it

  • compare(Object obj1, Object obj2)
  • equals(Object element)

Method of collection classes for sorting the List elements: we are using the sort method, and the syntax looks like the below

// To sort a given list. ComparatorClass must implement
// Comparator interface.
public void sort(List list, ComparatorClass c)

How to do collections.sort() work?

When we call the sort method, it internally calls the compare method and does the comparison.

Return 1: If the first element is greater than the second element
Return -1: If the second element is greater than the first element
Return 0: If both the elements are equals

The compare method uses this result and does swapping if required.

//A Java program to demonstrate Comparator interface
import java.io.*;
import java.util.*;

// A class 'Movie' that implements Comparable
class Movie implements Comparable<Movie>
{
   private double rating;
   private String name;
   private int year;

   // Used to sort movies by year
   public int compareTo(Movie m)
   {
      return this.year - m.year;
   }

   // Constructor
   public Movie(String nm, double rt, int yr)
   {
      this.name = nm;
      this.rating = rt;
      this.year = yr;
   }

   // Getter methods for accessing private data
   public double getRating() { return rating; }
   public String getName() { return name; }
   public int getYear() { return year; }
}

// Class to compare Movies by ratings
class RatingCompare implements Comparator<Movie>
{
   public int compare(Movie m1, Movie m2)
   {
      if (m1.getRating() < m2.getRating()) return -1;
      if (m1.getRating() > m2.getRating()) return 1;
      else return 0;
   }
}

// Class to compare Movies by name
class NameCompare implements Comparator<Movie>
{
   public int compare(Movie m1, Movie m2)
   {
      return m1.getName().compareTo(m2.getName());
   }
}

// Driver class
class Main
{
   public static void main(String[] args)
   {
      ArrayList<Movie> list = new ArrayList<Movie>();
      list.add(new Movie("Force Awakens", 8.3, 2015));
      list.add(new Movie("Star Wars", 8.7, 1977));
      list.add(new Movie("Empire Strikes Back", 8.8, 1980));
      list.add(new Movie("Return of the Jedi", 8.4, 1983));

      // Sort by rating : (1) Create an object of ratingCompare
      // (2) Call Collections.sort
      // (3) Print Sorted list
      System.out.println("Sorted by rating");
      RatingCompare ratingCompare = new RatingCompare();
      Collections.sort(list, ratingCompare);
      for (Movie movie: list)
         System.out.println(movie.getRating() + " " +
               movie.getName() + " " +
               movie.getYear());

      // Call overloaded sort method with RatingCompare
      // (Same three steps as above)
      System.out.println("\nSorted by name");
      NameCompare nameCompare = new NameCompare();
      Collections.sort(list, nameCompare);
      for (Movie movie: list)
         System.out.println(movie.getName() + " " +
               movie.getRating() + " " +
               movie.getYear());

      // Uses Comparable to sort by year
      System.out.println("\nSorted by year");
      Collections.sort(list);
      for (Movie movie: list)
         System.out.println(movie.getYear() + " " +
               movie.getRating() + " " +
               movie.getName()+" ");
   }
}

If you still have any doubts, then you can refer to the below method

Comparable vs Comparator

Comparable interfaceComparator interface
Present in java.lang packagePresent in java.util package
Defines only one important method i.e. public int compareTo(Object obj);Defines 2 method i.e.;public int compare(Object obj1, Object obj2);
public boolean equals(Object object);
It is used for default natural sorting order[DNSO]This is preferred for customized sorting order [CSO]
This interface needs to be implemented in the same class for which sorting is requiredA separate class is required to implement the Comparator interface
Elements of List can be sorted using a comparable interface example: Collection.sort(listItems);Elements of List can be sorted using comparator interface example: Collection.sort(listItems, comparator);
String & wrapper classes’ like Integer, Double, etc implement comparable interfaceThere are very few classes that implement a Comparator interface

I love open-source technologies and am very passionate about software development. I like to share my knowledge with others, especially on technology that's why I have given all the examples as simple as possible to understand for beginners. All the code posted on my blog is developed, compiled, and tested in my development environment. If you find any mistakes or bugs, Please drop an email to softwaretestingo.com@gmail.com, or You can join me on Linkedin.

Leave a Comment