Comparable vs Comparator in Java

Kasun Dissanayake
5 min readMar 30, 2022

In this article, I will explain about What is the difference between Comparator and Comparable. And when to use Comparable and Comparator.

First, let's identify the difference between these two sectors.

Comparable

  • Comparable provides a single sorting sequence. In other words, we can sort the collection on the basis of a single element such as id, name, and price.
  • Comparable affects the original class (the actual class is modified)
  • Comparable provides compareTo() method to sort elements.
  • Comparable is present on java.lang package.
  • We can sort the list elements of Comparable type by Collections.sort(List) method

Comparator

  • The Comparator provides multiple sorting sequences. In other words, we can sort the collection on the basis of multiple elements such as id, name,` price, etc.
  • Comparator provides compare() method to sort elements.
  • A Comparator is present in java.util package.
  • We can sort the list elements of Comparator type by Collections.sort(List, Comparator) method.

Code explanation

Here I have created a Student class to explain these theories. First, use Comparable Interface in Student class(You can implement the Comparable Interface). Then you have to override the compareTo method. Inside the compareTo method, you can write the logic. This is a single sorting implementation. So that you can only sort by one field either ID or name. I am going to implement a sorting mechanism based on the ID.

public class Student implements Comparable<Student>{

private int id;
private String name;

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

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public boolean equals(Object obj){
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Student student = (Student) obj;
return id == student.id && Objects.equals(name, student.name);
}


@Override
public int compareTo(Student student) {
if (id == student.id){
return 0;
}else if (id > student.id){
return 1;
}else{
return -1;
}
}
}

Now create 3 different using Student Class and put them into an array. Let’s try to sort these students using student ID. First of all, try to print the List, and then you can see they are not in order.

public static void main(String[] args) {

List<Student> studentList = new ArrayList<>();
Student student1 = new Student(327, "Kasun");
Student student2 = new Student(100, "Dasun");
Student student3 = new Student(167, "Thisun");

studentList.add(student1);
studentList.add(student2);
studentList.add(student3);

for(int i = 0; i < studentList.size(); i++) {
System.out.println(studentList.get(i).getId());
}


}

To sort these Custom Student Objects, you need to use the sort method in the Collection Framework.

Collections.sort(studentList);

Output:

Now in the future, I will get a requirement not to use ID and use a sorting algorithm to sort by name. Now you need to change the code again. Because I just implemented the sorting mechanism for the Student ID only. In the case of Comparable, it is not dynamic. It is always hardcoded. Once you get a requirement you need to change the code again and again. That is not recommended. So that we can use Comparator for this. When you are using a single sorting algorithm then go for Comparable. If not you can use Comparator.

Now I am going to create a Class for IdComparator and NameComparator. Why do I need Comparator classes for each field? Rather than hardcoding in the same class you can create several Comparator classes and use those in your main classes when you want.

Create IdComparator class and implements the Comparator Interface. Then you need to override the methods which you want.

public class IdComparator implements Comparator<Student> {
@Override
public int compare(Student student1, Student student2) {
if (student1.getId() == student2.getId()){
return 0;
}else if (student1.getId() > student2.getId()){
return 1;
} else {
return -1;
}
}
}

Like this, you can add NameComparator also.

public class NameComparator implements Comparator<Student> {
@Override
public int compare(Student student1, Student student2) {
return student1.getName().compareTo(student2.getName());
}
}

Now in the main method, you can use the sort method to sort any custom object which you want. Just give the comparator name as the second parameter as an Object. Here the first one will be the Name Comparator(sort by Name) and the second one will be the ID Comparator(sort by ID).

Collections.sort(studentList, new NameComparator());orCollections.sort(studentList, new IdComparator());

If we sort by the Name using NameComparator output will be like this. It will show the output Student Names in ascending order: Dasun, Kasun and Thisun

Interview Question

What happens if two Objects have the same sorting values? Let's assume 2 students have the same Student Id(Normally Students IDs are unique values. For this example Let’s assume there are 2 students who are having the same Student Id Numbers) and the names are different. What can we do about this? Basically, we need to sort these students' IDs first and if they are the same we can go for a Name Comparison.

Let's change the code to compare the ID and well as the Name. In the code we need to check the ID first, if they are the same then we can compare Students' Names. Go to IdComparator compare method and add the name comparison code inside the first if section(This section says that the two ids are the same).

if (o1.getId() ==  o2.getId()){   return o1.getName().compareTo(o2.getName());}else if (o1.getId() > o2.getId()){   return 1;} else {   return -1;}

Here I added Student Ids as 327, 100, 167, and 327. First, it will sort by the Student Id and then you can see the 327 Id Number is the same for two students(Kasun and Aruna). Now we can compare those two with the Name. Aruna starts with ‘A’ and Kasun starts with ‘K’ so obviously Aruna should occur first then Kasun.

So you can provide your custom sorting using Comparator. I hope this concept is clear for you and when to use Comparator and Comparable. That's all about this tutorial. See you in the next tutorial.

Thank You!

--

--

Kasun Dissanayake

Senior Software Engineer at IFS R & D International || Former Software Engineer at Pearson Lanka || Former Associate Software Engineer at hSenid Mobile