Comparable and Comparator

Comparable:
  • if the object(class) is in your control and you can make them implement comparable interface
  • Want to define a default (natural) ordering behaviour of the object
Comparator:
  • if the object is outside of your control(the class is imported through jars) and you cannot make them implement Comparable.
  • Want to define an external controllable ordering behaviour, this can override the default ordering behaviour.
Example: (without implementing comparable and comparator) 
public class Employee  {
 private String firstName;
 private String lastName;
 private int id;

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

}
Test
import java.util.Arrays;

public class Test {

 public static void main(String[] args) {

  Employee[] employees = new Employee[4];
  employees[0] = new Employee();
  employees[0].setFirstName("Ram");
  employees[0].setLastName("Babu");
  employees[0].setId(12);

  employees[1] = new Employee();
  employees[1].setFirstName("Hari");
  employees[1].setLastName("Prasad");
  employees[1].setId(21);

  employees[2] = new Employee();
  employees[2].setFirstName("Sadan");
  employees[2].setLastName("Gogula");
  employees[2].setId(10);

  employees[3] = new Employee();
  employees[3].setFirstName("Hari");
  employees[3].setLastName("Bathini");
  employees[3].setId(11);
  
  Arrays.sort(employees);
  
 }
}
will get below exception

Exception in thread "main" java.lang.ClassCastException: Employee cannot be cast to java.lang.Comparable
at java.util.Arrays.mergeSort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at comparableAndComparator.Test.main(Test.java:30)

To avoid this, we need to implement the java.lang.Comparable/java.util.Comparator interface .
Comparable :
This interface has one method, compareTo, which determines how to compare two instances of the class.
public int compareTo(Object o);
After implementing the comparable interface the Employee class.

public class Employee implements Comparable {
 private String firstName;
 private String lastName;
 private int id;

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 @Override
 public int compareTo(Employee compareEemployee) {
  int compareEemployeeId = ((Employee) compareEemployee).getId();
  return this.id - compareEemployeeId;

 }
}
Test
import java.util.Arrays;

public class Test {

 public static void main(String[] args) {

  Employee[] employees = new Employee[4];
  employees[0] = new Employee();
  employees[0].setFirstName("Ram");
  employees[0].setLastName("Babu");
  employees[0].setId(12);

  employees[1] = new Employee();
  employees[1].setFirstName("Hari");
  employees[1].setLastName("Prasad");
  employees[1].setId(21);

  employees[2] = new Employee();
  employees[2].setFirstName("Sadan");
  employees[2].setLastName("Gogula");
  employees[2].setId(10);

  employees[3] = new Employee();
  employees[3].setFirstName("Hari");
  employees[3].setLastName("Bathini");
  employees[3].setId(11);
  
  Arrays.sort(employees);
  
  for(Employee emp : employees){
   System.out.println("after sorting Id:"+emp.getId());
   System.out.println("after sorting First Name :"
     + emp.getFirstName());
  }
  
  
  
 }
}
Sort based on default behavior (Id)
Out put :
after sorting  Id :10
after sorting First Name :Sadan
after sorting Id :11
after sorting First Name :Hari
after sorting  Id :12
after sorting First Name :Ram
after sorting  Id :21
after sorting First Name :Hari

Comparator:

Comparator interface is used when an extra logic is required to sort the objects. One need to override compare(Object obj1, Object obj2) method.
For example you want the list of Employee object to be sorted on the basis of first name and also on the other hand doesnt want to change the Employee class default sorting implementation or Employee class is a jar so no code modification in it can be done.

Need to create the Employee Custom comparatore by implementing Comparable interfaceimport java.util.Comparator;
public class EmpCustomComparator implements Comparator {
 @Override
 public int compare(Employee e1, Employee e2) {
   String p1Name = e1.getFirstName();
   String p2Name = e2.getFirstName();
   return p1Name.compareTo(p2Name);
 }
}
Use the customcomparator to compare the Employee objects.
import java.util.Arrays;

public class Test {

 public static void main(String[] args) {

  Employee[] employees = new Employee[4];
  employees[0] = new Employee();
  employees[0].setFirstName("Ram");
  employees[0].setLastName("Babu");
  employees[0].setId(12);

  employees[1] = new Employee();
  employees[1].setFirstName("Hari");
  employees[1].setLastName("Prasad");
  employees[1].setId(21);

  employees[2] = new Employee();
  employees[2].setFirstName("Sadan");
  employees[2].setLastName("Gogula");
  employees[2].setId(10);

  employees[3] = new Employee();
  employees[3].setFirstName("Hari");
  employees[3].setLastName("Bathini");
  employees[3].setId(11);

  Arrays.sort(employees, new EmpCustomComparator());

  for (Employee emp : employees) {
   System.out.println("after sorting Id :" + emp.getId());
   System.out.println("after sorting First Name :"
     + emp.getFirstName());
  }

 }
} 
Sort based on custom behavior (first name)
Output:
after sorting Id :21
after sorting First Name :Hari
after sorting Id :11
after sorting First Name :Hari
after sorting Id :12
after sorting First Name :Ram
after sorting Id :10
after sorting First Name :Sadan

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...