Pages Navigation Menu

Coding is much easier than you think

Differences between Comparator and Comparable

Differences between Comparator and Comparable

 
One of the common asked interview question “What are differences between Comparator and Comparable”? Or “How will you sort collection of employee objects by its id or name”.
 
For this we can use two interfaces, Comparator and Comparable. Before we actually see differences, let me give you brief introduction of both.
 
Comparable interface:
 
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 which 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 must implement Comparable interface.
 
Comparator interface:
 
Comparator is an interface from java.util package. It includes two abstract methods – compare() and equals().

A comparator object (a class which implements Comparator interface) can compare any two objects and these two objects are passed as parameters to compare() method. That is, two objects of an Employee, like emp1 and emp2 can be passed.

The class which would like to sort the objects using Comparator must implement Comparator interface.
 
Recommended Article

 
Signature of the methods existing in Comparable and Comparator interfaces
 
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 returns

a) A positive integer if obj1 is greater than obj2.
b) Zero if obj1 and obj2 are equal.
c) A negative integer if obj1 is less than obj2.
 
How to use the methods?
 
Since 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.

 

1. A program using Comparable interface
 

import java.util.*;

class Employee implements Comparable<Employee> {
	private int salary;
	private String name;

	public Employee(int salary, String name) {
		this.salary = salary;
		this.name = name;
	}

	public int getSalary() {
		return salary;
	}

	public String getName() {
		return name;
	}

	public int compareTo(Employee emp) {
		return this.salary - emp.salary;
	}
}

public class EmployeeSortBySalary {
	public static void main(String args[]) {
		ArrayList<Employee> employeeList = new ArrayList<Employee>();
		employeeList.add(new Employee(50, "Haripriya"));
		employeeList.add(new Employee(40, "Venkat"));
		employeeList.add(new Employee(70, "Raman"));
		employeeList.add(new Employee(90, "Akathar"));
		employeeList.add(new Employee(30, "Farhan"));
		Collections.sort(employeeList);
		for (Employee emp : employeeList) {
			System.out.println(emp.getSalary() + " : " + emp.getName());
		}
	}
}

 
Output of the above program :
 

30 : Farhan
40 : Venkat
50 : Haripriya
70 : Raman
90 : Akathar

 
Explanation:
 

      class Employee implements Comparable<Employee>

 

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

Two member variables salary and name are declared and values are assigned through a constructor. Two getter methods are declared with which Employee salary and name are retrieved later.

 

public int compareTo(Employee emp)
{
 return this.salary - emp.salary;
}

 

The Comparable interface’s abstract method compareTo() is overridden where salary are compared.

Another class EmployeeSortBySalary is created which creates some Employee objects and adds them to ArrayList employeeList.

 

Collections.sort(employeeList);

 

The ArrayList object employeeList is passed to sort() method of Collections class. The sort() method sorts as per the Comparable interface compareTo() method as Employee class implements Comparable interface.
 
Sorting with name(String) field

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

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

Here, you may get a little confusion between the two compareTo() methods used in the above code. The compareTo() method used inside (this.name.compareTo(emp1.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.
 

2. A program using Comparator interface

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

 

import java.util.*;

class Employee
// Note that the Employee does not implement Comparator
{
	private int salary;
	private String name;

	public Employee(int salary, String name) {
		this.salary = salary;
		this.name = name;
	}

	public int getSalary() {
		return salary;
	}

	public String getName() {
		return name;
	}
} // Note that the EmployeeSortBySalary implements Comparator

public class EmployeeSortBySalary implements Comparator<Employee> {
	

	public static void main(String args[]) {
		ArrayList<Employee> employeeList = new ArrayList<Employee>();
		employeeList.add(new Employee(50, "Haripriya"));
		employeeList.add(new Employee(40, "Venkat"));
		employeeList.add(new Employee(70, "Raman"));
		employeeList.add(new Employee(90, "Akathar"));
		employeeList.add(new Employee(30, "Farhan"));
		
		Collections.sort(employeeList, new EmployeeSortBySalary());
		for (Employee st : employeeList) {
			System.out.println(st.getSalary() + " : " + st.getName());
		}
	}

	public int compare(Employee emp1, Employee emp2) {
		return emp1.getSalary() - emp2.getSalary();
	}
}

Output :
 

30 : Farhan
40 : Venkat
50 : Haripriya
70 : Raman
90 : Akathar

 
Explanation:
 
Here in the above program, one difference you can observe is, the Comparator interface is not implemented with Employee class but with another class. But in the case of Comparable, the Comparable interface is implemented with Employee class. That is, with Comparator, we can sort any class objects without changing the original class code.
 
The code explanation is the same of earlier Comparable, but with minor changes. 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.

In case of Comparator, it is Collections.sort(employeeList, new EmployeeSortBySalary()). The second parameter is an object of Comparator (a class that implements Comparator).

In case of Comparable, it is Collections.sort(employeeList).
 
In our next article we shall learn about When to use Comparator and Comparable in Java

About Mohaideen Jamil