Comparable and Comparator Interface

Java Comparable interface is used to sort or order the objects of user-defined class(Custom objects).The class must implements the java.lang.Comparable interface to compare its instances. This interface is belong to java.lang package and contains single method named compareTo(Object). It provide single sorting sequence only it means we can sort the elements on based on single data member only.  This interface has only one method:

public abstract int compareTo(T obj)

With the help of comparable interface we can sort the elements of:

  1. String objects
  2. Wrapper class objects
  3. User-defined class objects

Before we implement how to sort an objects of custom objects, lets see how we can sort elements of arrays and Wrapper classes that already implements Comparable interface.

Let us see an example:

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

public class ComparableTest {
  public static void main(String[] args) {

    int[] arr = {12,3,45,7,88,15};

    // Integer class implements Comparable interface so we can directly use the sort method
    Arrays.sort(arr);
    System.out.println("Sorted array elements -> " + Arrays.toString(arr));

    String[] names = {"Ishwar", "Ankit", "Shailendra"};
    // String class implements Comparable interface so we can directly use the sort method
    Arrays.sort(names);
    System.out.println("Sorted array elements -> " + Arrays.toString(names));

    List<String> roomMates = new ArrayList<String>();
    roomMates.add("Akhilesh");
    roomMates.add("Dam");
    roomMates.add("Ajay");
    roomMates.add("Himanshu");
    Collections.sort(roomMates);

    System.out.print("Sorted List: ");
    for(String name: roomMates) {
      System.out.println(name);
    }
  }
}

Output

Sorted array elements -> [3, 7, 12, 15, 45, 88]
Sorted array elements -> [Ankit, Ishwar, Shailendra]
Sorted List: Ajay
Akhilesh
Dam
Himanshu

As per above example, we have seen that how easy it is to sort the Arrays and list of objects that implements Comparable interface. However if we want to sort the objects of custom class then we need to implement the Comparable interface in our custom class.

Let us see an example:

Output:

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

class Student implements Comparable<Student>
{
  private String name;
  private int yob;
  private int rollNo;

  public Student(String name, int yob, int rollNo)
  {
    this.name = name;
    this.yob = yob;
    this.rollNo = rollNo;
  }

  // Used to sort data by yob(Year of Born)
  public int compareTo(Student testObj)
  {
    return this.yob - testObj.yob;
  }

  public String getName()   {  return name; }
  public int getYOB()      {  return yob;  }
  public int getRollNo() 	{ return rollNo; }
}

public class ComparableCustomObjectTest {

  public static void main(String[] args) {
    ArrayList<Student> arrayList = new ArrayList<Student>();
    arrayList.add(new Student("Ankit", 1989, 1));
    arrayList.add(new Student("Ishwar", 1990, 2));
    arrayList.add(new Student("Hemant", 1988, 3));

    Collections.sort(arrayList);
    System.out.println("After sorting by their year of born: ");
    for(Student std : arrayList) {
      System.out.println(std.getName() + " " + std.getYOB() + " " + std.getRollNo());
    }
  }
}

Output:

After sorting by their year of born: 
Hemant 1988 3
Ankit 1989 1
Ishwar 1990 2

Now, suppose if we want to sort name by their names and their roll numbers too. Then it is not possible to sort by two or more different test field as we have only one chance to implement the compareTo() method under comparable interface. We can resolve this using Comparator interface.

Unlike Comparable, Comparator is external to the element type we are comparing. We can create multiple separate classes (that implement Comparator) to compare by different members.

Let’s see an example so that we can understand it better. In this example we have created few java classes:

  1. Employee.java
  2. NameComparatorTest.java
  3. YOBComparatorTest
  4. ComparatorCustomObjectTest

Let’s see these classes one by one:

Employee.java

This class contains three fields name, yob and empId.

class Employee
{
  String name;
  int yob;
  int empId;

  // Constructor
  public Employee(String name, int yob, int empId)
  {
    this.name = name;
    this.yob = yob;
    this.empId = empId;
  }

  public String getName()   {  return name; }
  public int getYOB()      {  return yob;  }
  public int getEmpId() 	{ return empId; }

}

NameComparatorTest.java

import java.util.Comparator;

public class NameComparatorTest implements Comparator<Employee>{

  public int compare(Employee emp1, Employee emp2) {
    return emp1.getName().compareTo(emp2.name);
  }
}

YOBComparatorTest

This class defines comparison logic based on the year of born. If yob of first employee is greater than the second, it will return positive value. If yob of first employee is less than the second, it will return negative value. And if yob  of both objects are equal, it will return 0.

import java.util.Comparator;

public class YOBComparatorTest implements Comparator<Employee>{

  public int compare(Employee emp1, Employee emp2) {
    if(emp1.yob==emp2.yob) {
      return 0;
    } else if(emp1.yob>emp2.yob) {
      return 1;
    } else 
      return -1;
  }

}

ComparatorCustomObjectTest

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

public class ComparatorCustomObjectTest {

  public static void main(String[] args) {
    ArrayList<Employee> arrayList = new ArrayList<Employee>();
    arrayList.add(new Employee("Ankit", 1989, 101));
    arrayList.add(new Employee("Ishwar", 1990, 102));
    arrayList.add(new Employee("Hemant", 1988, 103));

    System.out.println("Sorting By Name: ");
    Collections.sort(arrayList, new NameComparatorTest());
    for(Employee emp : arrayList) {
      System.out.println(emp.getName() + " " + emp.getYOB() + " " + emp.getEmpId());
    }

    System.out.println("\nSorting By Year Of Born: ");
    Collections.sort(arrayList, new YOBComparatorTest());
    for(Employee emp : arrayList) {
      System.out.println(emp.getName() + " " + emp.getYOB() + " " + emp.getEmpId());
    }
  }

}

Output:

Sorting By Name: 
Ankit 1989 101
Hemant 1988 103
Ishwar 1990 102

Sorting By Year Of Born: 
Hemant 1988 103
Ankit 1989 101
Ishwar 1990 102

Comparable Vs Comparator

Comparable and Comparator both are interfaces and can be used to sort collection elements. Below are few differences:

Comparable Comparator
It comes under java.lang package. It comes under java.util package.
Comparable interface affects the actual class it means it modify the original class. Comparator interface does not affect the original class.
Sorting must be in same class whose objects are being sorted and also we can sort the collection on the basis of single element. Sorting logic adds in separate class. So we can write different sorting based on different elements or attributes of objects to be sorted.
Class whose objects to be sorted must implement this interface. Class whose objects to be sorted do not need to implement this interface.Some other class can implement this interface.
Here we use the given method i.e. Collections.sort(List). Here objects will be sorted on the basis of CompareTo method. Here we use the given method i.e. Collections.sort(List, Comparator). Here objects will be sorted on the basis of Compare method in Comparator.