Comparable vs Comparator

Comparable and Comparator both the interfaces are used to sort Collection of objects in certain order. Implementing Comparable interface allows us to achieve default or natural ordering where implementing a Comparator allow us to sort Collection in other than natural ordering.

 

Comparable interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class’s natural ordering and the class’s compareTo() method is referred to as its natural comparison method. Where a Comparator is a comparison function which imposes a total ordering of Collection of objects when Comparator object is passed to sort() method of Collections or Array class. Comparators can also be used to control the order of certain data structures or to provide an ordering for collections of objects that don’t have a natural ordering(not implementing comparable interface).

Comparable implementation:

Lets take our Employee class again which implements Comparable interface and override compareTo method like below.

@Override 
public int compareTo(Employee emp) { 
       if(this.salary > emp.salary) {
          return 1; 
       } else if(this.salary < emp.salary) {
          return -1; 
       }
       return 0; 
}

So you can decode what is written above i.e. All the Employees will be sorted based on their Salary in increasing order.

// e1, e2... are Employee class object declared already with different salaries
// var is Java10 compliant keyword. 
var employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9); 
System.out.println(employees); 
Collections.sort(employees); 
System.out.println(employees);

Point to be noted here is that you still have to call Collection.sort(…) method and pass your collection object there.

 

Comparator implementation:

We have to create new class (EmployeeNameComparator) which implements Comparator interface and override compare(…) method like below.

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

and to consume this implementation, we need to create an object of EmployeeNameComparator and pass it as second argument in sort method of Collections class.

// e1, e2... are Employee class object declared already with different salaries
// var is Java10 compliant keyword. 
var employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9); 
System.out.println(employees); // Default order or all the employees
Collections.sort(employees, new EmployeeNameComparator()); 
System.out.println(employees); // Employees will be sorted based on
                               // their name in ascending order

 

We can create as many as Comparators we want and pass their objects sort method.

Our Employee class can also implements both the interface at the same time and override their respective methods. It wont be a good design to pass Employee class object as comparator of sort method.

Git Code: https://github.com/tektutorial/java-design/tree/master/src/com/tektutorial/demo

 

Hope this clear your doubts.