Comparable is for objects with a natural ordering. The object itself knows how it is to be ordered.If any class implement Comparable interface in Java then collection of that object either List or Array can be sorted automatically by using Collections.sort() or Arrays.sort() method and object will be sorted based on there natural order defined by CompareTo method.
Comparator is for objects without a natural ordering or when you wish to use a different ordering.
Natural ordering is the Ordering implemented on the objects of each class. This ordering is referred to as the class’s natural ordering.For example Strings Natural Ordering is defined in String Class
Comparable
Compares object of itself with some other objects.Comparable overrides compareTo
Employee.java
package com.acme.users;
public class Employee implements Comparable<Employee> {
public String EmpName;
public Integer EmpId;
public Integer Age;
public Employee(Integer pEmpId, String pEmpName, Integer pAge)
{
this.EmpName = pEmpName;
this.EmpId = pEmpId;
this.Age = pAge;
}
public String getEmpName() {
return EmpName;
}
public void setEmpName(String empName) {
EmpName = empName;
}
public Integer getEmpId() {
return EmpId;
}
public void setEmpId(Integer empId) {
EmpId = empId;
}
public Integer getAge() {
return Age;
}
public void setAge(Integer age) {
Age = age;
}
@Override
public int compareTo(Employee arg0)
{
if(this.getEmpId() == arg0.getEmpId())
return 0;
else if (this.getEmpId() > arg0.getEmpId())
return 1;
else
return -1;
}
}
EmpDashBoard.java
package com.acme.users;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class EmpDashBoard {
public static void main(String[] args) {
List<Employee> arrEmpList = new ArrayList();
Employee objEmp1 = new Employee(101, "Ahmed", 31);
Employee objEmp2 = new Employee(127, "Mahesh", 24);
Employee objEmp3 = new Employee(109, "Viparna", 85);
Employee objEmp4 = new Employee(101, "Abdul", 26);
Employee objEmp5 = new Employee(104, "Muthu", 23);
Employee objEmp6 = new Employee(115, "Monalisa", 25);
arrEmpList.add(objEmp1);
arrEmpList.add(objEmp2);
arrEmpList.add(objEmp3);
arrEmpList.add(objEmp4);
arrEmpList.add(objEmp5);
arrEmpList.add(objEmp6);
System.out.println("Sorted based on Natural Sorting(Emp Id)");
System.out.println("Before Sorting");
dispListContent(arrEmpList);
Collections.sort(arrEmpList);
System.out.println("After Sorting");
dispListContent(arrEmpList);
}
public static void dispListContent(List<Employee> parrEmployeeLst) {
System.out.println(" ");
System.out.println("EmpId" + " " + "EmpName" + " " + "Age");
System.out.println("---------------------------");
for (Employee object : parrEmployeeLst) {
System.out.print(object.getEmpId() + " ");
System.out.print(object.getEmpName() + " ");
System.out.println(object.getAge() + " ");
}
}
}
Output
Sorted based on Natural Sorting(Emp Id)
Before Sorting
EmpId EmpName Age
---------------------------
101 Ahmed 31
127 Mahesh 24
109 Viparna 85
101 Abdul 26
104 Muthu 23
115 Monalisa 25
After Sorting
EmpId EmpName Age
---------------------------
101 Ahmed 31
101 Abdul 26
104 Muthu 23
109 Viparna 85
115 Monalisa 25
127 Mahesh 24
Comparator
In some situations, you may not want to change a class and make it comparable. In such cases, Comparator can be used.Comparator overrides compare
Comparator provides a way for you to provide custom comparison logic for types that you have no control over.
In the below Example I have Sorted the Employee class Objects based on Name(EmpNameComparator), Age(EmpAgeComparator) and based on EmpIDName(EmpIdNameComparator)
EmpDashBoard.java
package com.acme.users;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class EmpDashBoard {
public static void main(String[] args) {
List<Employee> arrEmpList = new ArrayList();
Employee objEmp1 = new Employee(101, "Ahmed", 31);
Employee objEmp2 = new Employee(127, "Mahesh", 24);
Employee objEmp3 = new Employee(109, "Viparna", 85);
Employee objEmp4 = new Employee(101, "Abdul", 26);
Employee objEmp5 = new Employee(104, "Muthu", 23);
Employee objEmp6 = new Employee(115, "Monalisa", 25);
arrEmpList.add(objEmp1);
arrEmpList.add(objEmp2);
arrEmpList.add(objEmp3);
arrEmpList.add(objEmp4);
arrEmpList.add(objEmp5);
arrEmpList.add(objEmp6);
System.out.println("Sorted based on Natural Sorting(Emp Id)");
System.out.println("Before Sorting");
dispListContent(arrEmpList);
System.out.println("Sorting based on Emp Name");
Collections.sort(arrEmpList, new EmpNameComparator());
dispListContent(arrEmpList);
System.out.println("Sorting based on Emp Age");
Collections.sort(arrEmpList, new EmpAgeComparator());
dispListContent(arrEmpList);
System.out.println("Sorting based on EmpId and Name");
Collections.sort(arrEmpList, new EmpIdNameComparator());
dispListContent(arrEmpList);
}
public static void dispListContent(List<Employee> parrEmployeeLst) {
System.out.println(" ");
System.out.println("EmpId" + " " + "EmpName" + " " + "Age");
System.out.println("---------------------------");
for (Employee object : parrEmployeeLst) {
System.out.print(object.getEmpId() + " ");
System.out.print(object.getEmpName() + " ");
System.out.println(object.getAge() + " ");
}
}
}
EmpNameComparator.java
public class EmpNameComparator implements Comparator<Employee>{
@Override
public int compare(Employee o1, Employee o2) {
String a = o1.getEmpName();
String b = o2.getEmpName();
//Strings Natural Order Comparable Method
int compare = a.compareTo(b);
if (compare > 0){
return 1;
}
else if (compare < 0) {
return -1;
}
else {
return 0;
}
}
}
EmpAgeComparator.java
public class EmpAgeComparator implements Comparator<Employee> {
@Override
public int compare(Employee o1, Employee o2) {
Integer a = o1.getAge();
Integer b = o2.getAge();
if (a > b){
return 1;
}
else if (a < b) {
return -1;
}
else {
return 0;
}
}
}
EmpIdNameComparator.java
public class EmpIdNameComparator implements Comparator<Employee>{
@Override
public int compare(Employee o1, Employee o2) {
String a = o1.getEmpName();
String b = o2.getEmpName();
int i = Integer.compare(o1.getEmpId(), o2.getEmpId());
if (i != 0) return i;
return a.compareTo(b);
}
}
Output
Before Sorting
EmpId EmpName Age
---------------------------
101 Ahmed 31
127 Mahesh 24
109 Viparna 85
101 Abdul 26
104 Muthu 23
115 Monalisa 25
Sorting based on Emp Name
EmpId EmpName Age
---------------------------
101 Abdul 26
101 Ahmed 31
127 Mahesh 24
115 Monalisa 25
104 Muthu 23
109 Viparna 85
Sorting based on Emp Age
EmpId EmpName Age
---------------------------
104 Muthu 23
127 Mahesh 24
115 Monalisa 25
101 Abdul 26
101 Ahmed 31
109 Viparna 85
Sorting based on EmpId and Name
EmpId EmpName Age
---------------------------
101 Abdul 26
101 Ahmed 31
104 Muthu 23
109 Viparna 85
115 Monalisa 25
127 Mahesh 24
comparable for natural order, (natural order definition is obviously open to interpretation), and write a comparator for other sorting or comparison needs.
If there is a natural or default way of sorting Object already exist during development of Class than use Comparable. This is intuitive and you given the class name people should be able to guess it correctly like Strings are sorted chronically, Employee can be sorted by there Id etc. On the other hand if an Object can be sorted on multiple ways and client is specifying on which parameter sorting should take place than use Comparator interface. for example Employee can again be sorted on name, salary or department and clients needs an API to do that. Comparator implementation can sort out this problem.