Comparator Vs Comparable in Java

The Comparator in Java used  for Sorting of members in data structures like TreeSet or TreeMap.The Comparable interface is also using for the same purpose. But there are  few differences between these two interfaces.This chapter deals with Comparator  Vs Comparable in Java

1)Comparable interface is having the method compareTo(Object arg). But Comparator is having method compare(Object arg1 , Object arg2). The working of  these two methods can be well understood by analyzing examples.In our case we need to sort few Student objects in ascending order of attribute ‘id’.

First Let us see the working of Comparable interface.Here the Student.java is implementing the Comparable interface. So the compareTo() method does the necessary comparison to sort the objects in ascending order of  ‘id’.

public class Student implements Comparable {
private int id;
private String name;
public Student(int number, String name) {
this.id = number;
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;
}
public String toString() {
return "Id = " + getId() + " ; Name = " + getName();
}
public int compareTo(Object o) {
return getId() - ((Student) o).getId();
}
}

Now let us see the ComparableSample.java.It is having the main() method.The addItems() method is adding few Student objects . Then the  displayItems() method is displaying the items in the sorted order.

public class ComparableSample {
private Set set = null;
public ComparableSample() {
set = new TreeSet();
}
public void addItems() {
Student student1 = new Student(2, "Bijoy");
Student student2 = new Student(1, "Karthik");
Student student3 = new Student(3, "Dexter");
Student student4 = new Student(4, "Sasi");
set.add(student4);
set.add(student1);
set.add(student2);
set.add(student3);
}
public void displayItems() {
Iterator itr = set.iterator();
System.out.println("In ascending order");
while (itr.hasNext()) {
System.out.println((Student) itr.next());
}
}
public static void main(String[] args) {
ComparableSample sample = new ComparableSample();
sample.addItems();
sample.displayItems();
}
}

Let us verify the output.

Output

In ascending order

Id = 1 ; Name = Karthik

Id = 2 ; Name = Bijoy

Id = 3 ; Name = Dexter

Id = 4 ; Name = Sasi

Now let us see an example which sorts a number of Student objects  using Comparator. See the Student.java first.

public class Student {
private int id;
private String name;
public Student(int number, String name) {
this.id = number;
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;
}
public String toString() {
return "Id = " + getId() + " ; Name = " + getName();
}
}

Now let us see the ComparatorSample.java . In the constructor  we are initializing a TreeSet object with a Comparator instance as argument . The Comparator instance does the necessary comparison for sorting. The Comparator  instance shown here sorts the set in ascending order

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class ComparatorSample {
private Set set = null;
public ComparatorSample() {
set = new TreeSet(new Comparator() {
public int compare(Student student1, Student student2) {
return student1.getId() - student2.getId();
}
});
}
public void addItems() {
Student student1 = new Student(2, "Bijoy");
Student student2 = new Student(1, "Karthik");
Student student3 = new Student(3, "Dexter");
Student student4 = new Student(4, "Sasi");
set.add(student4);
set.add(student1);
set.add(student2);
set.add(student3);
}
public void displayItems() {
Iterator itr = set.iterator();
System.out.println("In ascending order");
while (itr.hasNext()) {
System.out.println((Student) itr.next());
}
}
public static void main(String[] args) {
ComparatorSample sample = new ComparatorSample();
sample.addItems();
sample.displayItems();
}
}

Now let us verify our output.

Output

In ascending order

Id = 1 ; Name = Karthik

Id = 2 ; Name = Bijoy

Id = 3 ; Name = Dexter

Id = 4 ; Name = Sasi

2)From the method arguments itself , it is clear that compareTo() method of Comparable  is calling on current object.It compares the current object with  the object which is coming as argument.But the compare() method receives two arguments and comparing those two argument objects.

3)The purpose of these two interfaces is to sort the collection elements in an order. If we want objects of a particular class in a collection (example: TreeSet)  , and   we are interested in Comparable only .In that case the class whose objects needs to be stored in the structure should implement Comparable. If we are interested in Comparator then the class whose objects needs to be stored  need not implement Comparator(We can create a separate class implementing Comparator which does comparison). In other words we cannot make a separate comparison class by implementing Comparable. But we can make a separate comparison class by implementing Comparator.

4)Suppose we need a group of objects of a particular class to be sorted in an order. And we implemented that particular class with Comparable . In the later stage of our application we need to sort  a group of objects of the same class  in another order. In that case  Comparable is useless. We cannot make multiple Comparable implementations for a particular class. But if we are using Comparator , it is possible to define any number Comparator units as our wish.

So let us discuss an example on point 4 explained above .

We have an Student.java class which implements the Comparable interface to make objects of employee.java in ascending order of attribute ‘ id’.

public class Student implements Comparable {
private int id;
private String name;
public Student(int number, String name) {
this.id = number;
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;
}
public String toString() {
return "Id = " + getId() + " ; Name = " + getName();
}
public int compareTo(Object o) {
return getId() - ((Student) o).getId();
}
}

And at certain point of time  , we need the objects in descending order of id .And also  later we need objects in ascending order of attribute ‘name’. So we should have two Comparator instances . It is explained in the Main.java .

import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class Main {
public Main() {
}

public void addItemsAscendingId() {
Set set = new TreeSet();
Student student1 = new Student(2, "Bijoy");
Student student2 = new Student(1, "Karthik");
Student student3 = new Student(3, "Dexter");
Student student4 = new Student(4, "Sasi");
set.add(student4);
set.add(student1);
set.add(student2);
set.add(student3);
System.out.println("In ascending order of id ");
Iterator itr = set.iterator();
while (itr.hasNext()) {
System.out.println((Student) itr.next());
}
}
public void addItemsdescId() {
Set set = new TreeSet(new Comparator() {
public int compare(Student student, Student student1) {
return student1.getId() - student.getId();
}
});
Student student1 = new Student(2, "Bijoy");
Student student2 = new Student(1, "Karthik");
Student student3 = new Student(3, "Dexter");
Student student4 = new Student(4, "Sasi");
set.add(student4);
set.add(student1);
set.add(student2);
set.add(student3);
System.out.println("In descending order of id ");
Iterator itr = set.iterator();
while (itr.hasNext()) {
System.out.println((Student) itr.next());
}
}
public void addItemsAscendingName(){
Set set = new TreeSet(new Comparator() {
public int compare(Student student, Student student1) {
return student.getName().compareTo(student1.getName());
}
});
Student student1 = new Student(2, "Bijoy");
Student student2 = new Student(1, "Karthik");
Student student3 = new Student(3, "Dexter");
Student student4 = new Student(4, "Sasi");
set.add(student4);
set.add(student1);
set.add(student2);
set.add(student3);
System.out.println("In ascending order of name ");
Iterator itr = set.iterator();
while (itr.hasNext()) {
System.out.println((Student) itr.next());
}
}
public static void main(String[]args){
Main main = new Main();
main.addItemsAscendingId();
main.addItemsdescId();
main.addItemsAscendingName();
}
}

So if we are using Comparator then  we can define new comparing strategies . If we use Comparable alone  , we cannot get different sorting strategies.Let us verify the output.

Output

In ascending order of id

Id = 1 ; Name = Karthik

Id = 2 ; Name = Bijoy

Id = 3 ; Name = Dexter

Id = 4 ; Name = Sasi

In descending order of id

Id = 4 ; Name = Sasi

Id = 3 ; Name = Dexter

Id = 2 ; Name = Bijoy

Id = 1 ; Name = Karthik

In ascending order of name

Id = 2 ; Name = Bijoy

Id = 3 ; Name = Dexter

Id = 1 ; Name = Karthik

Id = 4 ; Name = Sasi

So this makes our understanding clear.

See Related Topics:

Comparable in Java

Comparator in Java

Collections in Java

Iterator in Java