Comparator and Comparable Interface in Java
Java Collections Tutorial List :
1:Introduction to Java Collections Framework 2:ArrayList in java with example programs 3:ArrayList Important methods 4:How to sort ArrayList in Java 5:Comparator and Comparable Interface in Java
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.
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:
Value | Meaning |
---|---|
Less than zero | The invoking object is less |
Greater than zero | The invoking object is greater |
Zero | The 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.
Related Articles