Adds

Comparator and Comparable Interface in Java

Java Collections Tutorial List :

Comparator and Comparable are two interfaces in Java API, which is used to compare two objects in Java.In this tutorial we will discuss how to use java.lang.Comparable and java.util.Comparator to sort a Java object based on its property value.


1. Sort an Array

To sort an Array, use the Arrays.sort() method.

package com.example;

import java.util.Arrays;

public class ArraySorting {

	public static void main(String args[]) {
		String[] name = new String[] { "Ravi", "Mukesh", "Sonu", "Vicky" };

		Arrays.sort(name);

		for (String string : name) {
			System.out.println("Names in sorted order : " + string);
		}
	}
}

Output :

Names in sorted order : Mukesh
Names in sorted order : Ravi
Names in sorted order : Sonu
Names in sorted order : Vicky


2. Sorting of ArrayList <integer> :

We can use Collection.sort method to sort ArrayList.

package com.example;

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

public class ListSorting {

	public static void main(String args[]) {
		ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(23);
		list.add(35);
		list.add(10);
		list.add(45);

		System.out.println("Before Sorting list element is :");
		for (int value : list) {
			System.out.println(value);
		}

		Collections.sort(list);

		/* List after sorting */
		System.out.println("After Sorting list is:");
		for (int value : list) {
			System.out.println(value);
		}
	}
}

Output :

Before Sorting list element is :
23
35
10
45
After Sorting list is:
10
23
35
45


Now let us sort an array of a custom class Employee.

Employee.java

package com.example;

public class Employee {

	private String name;
	private String email;
	private int age;
	private long salary;

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

	public String getName() {
		return name;
	}

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

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public long getSalary() {
		return salary;
	}

	public void setSalary(long salary) {
		this.salary = salary;
	}
}

Let us try to sort Employee class object using Arrays.sort() method as given in below code.

SortEmployee.java

package com.example;

import java.util.Arrays;

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

		Employee[] employee = new Employee[4];

		Employee emp1 = new Employee("Mukesh", "m@gmail.com", 27, 80000);
		Employee emp2 = new Employee("Ravi", "r@gmail.com", 25, 50000);
		Employee emp3 = new Employee("Sonu", "s@gmail.com", 23, 40000);
		Employee emp4 = new Employee("Vicky", "v@gmail.com", 23, 20000);

		employee[0] = emp1;
		employee[1] = emp2;
		employee[2] = emp3;
		employee[3] = emp4;

		Arrays.sort(employee);

		int i = 0;
		for (Employee emp : employee) {
			System.out.println("Employee Name " + ++i + " : " + emp.getName()
					+ ", Email : " + emp.getEmail() + ", Email : "
					+ emp.getEmail() + ", Age : " + emp.getAge()
					+ ", Salary : " + emp.getSalary());
		}

	}
}

When you will run this example you will get following error.Reason for this error is what you expect the Arrays.sort() will do? We have not mentioned what to sort in the Employee class.

Exception in thread "main" java.lang.ClassCastException: com.example.Employee cannot be cast to java.lang.Comparable
	at java.util.ComparableTimSort.countRunAndMakeAscending(Unknown Source)
	at java.util.ComparableTimSort.sort(Unknown Source)
	at java.util.ComparableTimSort.sort(Unknown Source)
	at java.util.Arrays.sort(Unknown Source)
	at com.example.SortEmployee.main(SortEmployee.java:20)

To sort an Object by its property, you have to make the Object implement the Comparable or Comparator interface by overriding its method compare and compareTo.

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.


Comparable Interface :

Comparable is an interface from java.lang package.This interface is used to impose natural ordering Sorting(natural ordering e.g 1,2,3 in numerals or 'a','b','c' in alphabetical order ) of the class that implements it.Class whose objects to be sorted must implement this interface.It includes only one abstract method compareTo() that is to be overridden by the programmer with his ordering code.

If any class implements comparable interface then collection of that object can be sorted automatically using Collection.sort() or Arrays.sort().Object will be sort on the basis of compareTo method in that class.If Comparable is implemented by a class it will compare object of itself with some other objects.

public int compareTo(Object o) :

Compares this object with the given object and returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the given object .compareTo(Object o) compares two instances of the class.Here, out of two instances to compare, one is instance itself on which method will be invoked, and other is passed as parameter o.

The result of the comparison is returned and is interpreted as shown below:

ValueMeaning
 
Less than zero The invoking object is less
Greater than zero The invoking object is greater
ZeroThe two Objects are equal.

Lets see how our Employee class will look after implementing Comparable interface.

Employee.java

package com.example;

public class Employee implements Comparable<Employee> {

	private String name;
	private String email;
	private int age;
	private long salary;

	public Employee(String name, String email, int age, long salary) {
		super();
		this.name = name;
		this.email = email;
		this.age = age;
		this.salary = salary;
	}

	public String getName() {
		return name;
	}

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

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public long getSalary() {
		return salary;
	}

	public void setSalary(long salary) {
		this.salary = salary;
	}

	@Override
	public int compareTo(Employee emp) {
		// let's sort the employee based on age in ascending order
		// returns a negative integer, zero, or a positive integer as this
		// employee id
		// is less than, equal to, or greater than the specified object.
		return (this.age - emp.age);
	}

	@Override
	public String toString() {
		return "Employee : " + name + " - " + email + " - " + age + " - "
				+ salary + "n";
	}
}

In the above code inside compare() method, we have simply returned the difference in employee age of two instances.

Lets test Sorting based on employee age.

SortEmployee.java

package com.example;

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

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

		Employee emp1 = new Employee("Mukesh", "m@gmail.com", 27, 80000);
		Employee emp2 = new Employee("Ravi", "r@gmail.com", 25, 50000);
		Employee emp3 = new Employee("Sonu", "s@gmail.com", 23, 40000);
		Employee emp4 = new Employee("Vicky", "v@gmail.com", 20, 20000);

		List<Employee> employees = new ArrayList<Employee>();
		employees.add(emp1);
		employees.add(emp2);
		employees.add(emp3);
		employees.add(emp4);

		// UnSorted List
		System.out.println(employees);

		Collections.sort(employees);
		// Default Sorting by employee age
		System.out.println(employees);
	}

}

In SortEmployee.java class, first print statement prints an unsorted list of employees and in second print statement, employees are sorted by their age.

Output :

[Employee : Mukesh - m@gmail.com - 27 - 80000n, Employee : Ravi - r@gmail.com - 25 - 50000n, Employee : Sonu - s@gmail.com - 23 - 40000n, Employee : Vicky - v@gmail.com - 20 - 20000n]
[Employee : Vicky - v@gmail.com - 20 - 20000n, Employee : Sonu - s@gmail.com - 23 - 40000n, Employee : Ravi - r@gmail.com - 25 - 50000n, Employee : Mukesh - m@gmail.com - 27 - 80000n]

Comparator Interface :

As you can see in the above example that Employees list is sorted by age in ascending order.

But in real time application you need to implement sorting based on different parameters. For example, some user would like to sort the employees based on Salary, some user would like to sort them based on the country bla bla. This is the situation where we need to use Comparator interface because Comparable Interface compareTo(Object o) method implementation can sort based on one field only and we can’t chose the field on which we want to sort the Object.

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 Employee, like emp1 and emp2 can be passed.

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

Employee.java

package com.jwt.core.java;

public class Employee {
	private int empId;
	private String empName;
	private int age;

	public Employee(int empId, String empName, int age) {
		this.empId = empId;
		this.empName = empName;
		this.age = age;
	}

	public int getEmpId() {
		return empId;
	}

	public void setEmpId(int empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String toString() {
		return "Employee : " + empId + " - " + empName + " - " + age;
	}
}

SortByEmpName.java

package com.jwt.core.java;

import java.util.Comparator;

public class SortByEmpName implements Comparator<Employee> {
	@Override
	public int compare(Employee emp1, Employee emp2) {
		return emp1.getEmpName().compareTo(emp2.getEmpName());

	}
}

SortByEmpId.java

package com.jwt.core.java;

import java.util.Comparator;

public class SortByEmpId implements Comparator<Employee> {

	@Override
	public int compare(Employee emp1, Employee emp2) {
		return emp1.getEmpId() - emp2.getEmpId();
	}

}

SortByEmpAge.java

package com.jwt.core.java;

import java.util.Comparator;

public class SortByEmpAge implements Comparator<Employee> {
	@Override
	public int compare(Employee emp1, Employee emp2) {
		return emp1.getAge() - emp2.getAge();
	}

}

Let us create a test class to sort employee based on different type of field.

ComparatorTest.java

package com.jwt.core.java;

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

public class ComparatorTest {
	public static void main(String[] args) {
		Employee emp1 = new Employee(1, "Mukesh", 27);
		Employee emp2 = new Employee(2, "Ravi", 25);
		Employee emp3 = new Employee(3, "Aayush", 18);
		Employee emp4 = new Employee(4, "Vicky", 21);

		List<Employee> employees = new ArrayList<Employee>();
		employees.add(emp1);
		employees.add(emp2);
		employees.add(emp3);
		employees.add(emp4);

		// UnSorted List
		System.out.println("Unsorted List : " + employees);

		Collections.sort(employees, new SortByEmpName());
		// Sorted by Employee Name
		System.out.println("Sorted by Name : " + employees);

		Collections.sort(employees, new SortByEmpId());
		// Sorted by Emp Id
		System.out.println("Sorted by Emp ID : " + employees);

		Collections.sort(employees, new SortByEmpAge());
		// Sorted by age
		System.out.println("Sorted by Employee Age : " + employees);
	}
}

Output :

Unsorted List : [Employee : 1 - Mukesh - 27, Employee : 2 - Ravi - 25, Employee : 3 - Aayush - 18, Employee : 4 - Vicky - 21]
Sorted by Name : [Employee : 3 - Aayush - 18, Employee : 1 - Mukesh - 27, Employee : 2 - Ravi - 25, Employee : 4 - Vicky - 21]
Sorted by Emp ID : [Employee : 1 - Mukesh - 27, Employee : 2 - Ravi - 25, Employee : 3 - Aayush - 18, Employee : 4 - Vicky - 21]
Sorted by Employee Age : [Employee : 3 - Aayush - 18, Employee : 4 - Vicky - 21, Employee : 2 - Ravi - 25, Employee : 1 - Mukesh - 27]

Now we are able to sort the collection of employees on any field using comparator interface.




comments powered by Disqus