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.