Comparable vs Comparator

At the outset, both are used for ordering the elements of a data structure in the way the programmer desires. Just they differ in their methods of implementation and usage with objects in comparison. These two interfaces are best suitable for ordering the objects depending on their fields. For example, student objects can be ordered on name or marks or age fields.

Study well the differences in Comparable vs Comparator and do not get confused between two where a Beginner should be careful.

What is Comparable?

Comparable is an interface from java.lang package. It includes only one abstract method compareTo() that is to be overridden by the programmer with his ordering code.

A comparable object (a class that implements Comparable interface) compares itself with another object. If the object obj1 would like to compare with obj2, call compareTo() method with obj1 and pass obj2 as parameter (like equals() method in case of strings).

The class which would like to sort the objects using Comparable should implement Comparable interface.

What is a Comparator?

Comparator is an interface from java.util package. It includes two abstract methods – compare() and equals().

A comparator object (a class that implements Comparator interface) can compare any two objects and these two objects are passed as parameters to compare() method. That is, two objects of a Student, like std1 and std2 can be passed.

The class which would like to sort the objects using Comparator should implement Comparator interface.

What are the signature of the methods existing in these interfaces?

Following are the signatures of the methods.

java.lang.Comparable interface

  • int compareTo(Object obj2): Compares two objects. With one object (current object, say obj1) the method is called and the other is passed as parameter (like obj2). The method returns an integer value depending on the objects under comparison as follows.

java.util.Comparator interface

  • int compare(Object obj1, Object obj2): Objects obj1 and obj2, under comparison, are passed as parameters. Returns an integer value depending on the objects under comparison as described below.

Both methods return the same. Returns

a) A positive integer value if obj1 is greater than obj2.
b) 0 value if obj1 and obj2 are equal.
c) A negative integer value if obj1 is less than obj2.

How to use the methods?

Being these methods are abstract, they must be overridden by the implementing classes.

The Comparable object is used along with Collections.sort(List) and Arrays.sort(Object[]) methods.

The Comparator object is used with Collections.sort(List, Comparator) and Arrays.sort(Object[], Comparator) methods.

Note: Similar notes is available with tutorials on Comparable and Comparator. It is advised to go through these before proceeding for the following programs.

I. A program using Comparable interface

In the earlier "Comparator example", Employee objects are sorted in ascending order as per the age field. Now let us go for another program where Student objects are sorted as per their marks.

import java.util.*;
class Student implements Comparable
{
  private int marks;
  private String name;

  public Student(int marks, String name)
  {
    this.marks = marks;
    this.name = name;
  }
  public int getMarks()
  {
    return marks;
  }
  public String getName()
  {
    return name;
  }
  public int compareTo(Student st1)
  {
    return this.marks - st1.marks;
  }
}

public class StudentSortByMarks
{
  public static void main(String args[])
  {
    List studentList = new ArrayList();
    studentList.add(new Student(50, "Rao"));
    studentList.add(new Student(40, "Seth"));
    studentList.add(new Student(60, "Kunal"));
    studentList.add(new Student(20, "Reddy"));
    studentList.add(new Student(30, "Nidhi"));

    Collections.sort(studentList);
    for(Student st : studentList)
    {
      System.out.println(st.getMarks() + " : " + st.getName());
    }
  }
}



Output screenshot on Comparable vs Comparator

      class Student implements Comparable

The Student class implements Comparable interface. Here, Comparable is designed to be generics; that is, Comparable object compares only Student objects.

Two instance variables marks and name are declared and values are assigned through a constructor. Two getter methods are declared with which Student marks and name are retrieved later.

  public int compareTo(Student st1)
  {
    return this.marks - st1.marks;
  }

The Comparable interface's abstract method compareTo() is overridden where marks are compared.

Another class StudentSortByMarks is created which creates some Student objects and adds them to ArrayList studentList.

     Collections.sort(studentList);

The ArrayList object studentList is passed to sort() method of Collections class. The sort() method sorts as per the Comparable interface compareTo() method as Student class implements Comparable interface.

     for(Student st : studentList)
     {
       System.out.println(st.getMarks() + " : " + st.getName());
     }

After the studentList is sorted, the elements are printed with enhanced for loop.

Sorting with name field

Now let us try sorting with name field. Just change the compareTo() method in Student class as follows.

     public int compareTo(Student st1) // compareTo() belongs to Comparable interface
     {
       return this.name.compareTo(st1.name);  // compareTo() belongs to String class
     }

Here, you may get a small confusion between the two compareTo() methods used in the above code. The compareTo() method used inside (this.name.compareTo(st1.name)) belongs to String class and not Comparable interface. compareTo() method of String class makes lexicographical comparison and returns three types of integers – positive, negative and 0.

But for the above change, all the code of the two programs is just same.

Comparable vs Comparator

The above screenshot gives the ordering of students with respect to their name.

II. A program using Comparator interface

Earlier you have seen one program "Comparator Example" where an ArrayList elements are sorted. For a better understanding of the subject, let us do the same Student class of Comparable but with Comparator.

One striking difference you can observe is, the Comparator interface is not implemented with Student class but with another class. But incase of Comparable, the Comparable interface is implemented with Student class. That is, with Comparator, we can sort any class objects without changing the original class code.

import java.util.*;
class Student       //observe, Student does not implement Comparator
{
  private int marks;
  private String name;

  public Student(int marks, String name)
  {
    this.marks = marks;
    this.name = name;
  }
  public int getMarks()
  {
    return marks;
  }
  public String getName()
  {
    return name;
  }
}                   //observe, StudentSortByMarks implements Comparator
public class StudentSortByMarks implements Comparator
{                     
  public int compare(Student st1, Student st2) 
  {
    return st1.getMarks() - st2.getMarks();
  }
  public static void main(String args[])
  {
    List studentList = new ArrayList();
    studentList.add(new Student(50, "Rao"));
    studentList.add(new Student(40, "Seth"));
    studentList.add(new Student(60, "Kunal"));
    studentList.add(new Student(20, "Reddy"));
    studentList.add(new Student(30, "Nidhi"));
    
    StudentSortByMarks ssbm = new StudentSortByMarks();
    Collections.sort(studentList, ssbm);
    for(Student st : studentList)
    {
      System.out.println(st.getMarks() + " : " + st.getName());
    }
  }
}


Comparable vs Comparator
Output screenshot on Comparable vs Comparator

The code explanation is the same of earlier Comparable, but with minor changes. The Comparator is implemented by StudentSortByMarks and not by Student. The method overridden is compare() (in the case of Comparable, it is compareTo()). The compare() method parameters are two objects under comparison; but with Comparable, the compareTo() method parameter is one, the other object calls the method.

One more difference is the usage of overloaded sort() method.

Incase of Comparator, it is Collections.sort(studentList, esbm). The second parameter is an object of Comparator (a class that implements Comparator).

Incase of Comparable, it is Collections.sort(studentList).

Both methods compareTo() and compare() return the same integer value. compareTo() of Comparable interface uses some predefined sorting order as did by Collections.sort(). But with Comparator you can dictate your sorting order.

Moreover, Comparable require an extra class to implement but Comparator does not require an extra class to implement this interface.

See with: class Student implements Comparable

See with: class Student //observe, Student does not implement Comparator
public class StudentSortByMarks implements Comparator

9 thoughts on “Comparable vs Comparator”

  1. Moreover, Comparable does not require an extra class to implement but Comparator require an extra class to implement this interface.

    It seem mistake, Comparable require an extra class to implement but Comparator does not require an extra class to implement this interface ??

  2. Sir How collections.sort() call compareTo(Student st1) method internally becoz not call this method StudentSortByMarks class

  3. Sir I dont knoiw the internal operation of the method.can you please brief..

    public int compareTo(Student st1) {
    return this.marks – st1.marks;
    }
    this.marks = current object and st1.marks = current object
    it will return 0.then how it sort the objects in ascending order

Leave a Comment

Your email address will not be published.