Comparable vs Comparator in Java

In this post, we will learn the difference between Comparable Interface and Comparator Interface in Java. This is a frequently asked question in Java interviews for beginners. Let's dive into it.

Difference between Comparable Interface and Comparator Interface in Java

Feature Comparable Interface Comparator Interface
Purpose Used for natural ordering of objects. Used for custom ordering of objects.
Interface Method Contains the compareTo() method. Does not impose any method.
Defined in Declared in the java.lang package. Declared in the java.util package.
Class Implementation Implemented by the class of the objects being compared. Implemented by a separate class that compares objects.
Single Sorting Criteria Provides a single sorting criterion. Allows multiple custom sorting criteria to be defined.
Intrinsic Sorting Order Objects must be modified to implement Comparable. Sorting logic can be defined without modifying objects.
Object Mutability Objects need to be changed if the sorting order changes. Objects remain unaffected by sorting order changes.
Natural Order Defines the default natural ordering for the class. Allows different custom orderings for the same class.
Example class Student implements Comparable<Student> { ... } class AgeComparator implements Comparator<Student> { ... }

Comparable Example

This example demonstrates that we create a list of Person objects and we compare each person's age by using the compateTo() method of Comparable Interface. In short, we are sorting persons by age in ascending order.
public class Person implements Comparable<Person> {

    private int id;
    private String name;
    private int age;

    public Person(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return this.name;
    }

    @Override
    public int compareTo(Person otherPerson) {
        return (this.getAge() - otherPerson.getAge());
    }
}
import java.util.ArrayList;

import java.util.Collections;
import java.util.List;

public class PersonSorterInASC {
    public static void main(String[] args) {
        sortUserDefinedObjectsInAsc();
    }

    private static void sortUserDefinedObjectsInAsc() {
        List<Person> persons = new ArrayList<Person>();
        Person person1 = new Person(59, "John", 40);
        Person person12 = new Person(67, "Roger", 25);
        Person person13 = new Person(45, "Steven", 30);
        persons.add(person1);
        persons.add(person12);
        persons.add(person13);

        System.out.println("Before Sorting : " + persons);
        Collections.sort(persons);
        System.out.println("After Sorting : " + persons);
    }
}
Output:
Before Sorting : [John, Roger, Steven]
After Sorting : [Roger, Steven, John]

Comparator Example

import java.time.LocalDate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComparatorExample {
    public static void main(String[] args) {
        List<Employee> employees = new ArrayList<>();

        employees.add(new Employee(1010, "Rajeev", 100000.00, LocalDate.of(2010, 7, 10)));
        employees.add(new Employee(1004, "Chris", 95000.50, LocalDate.of(2017, 3, 19)));
        employees.add(new Employee(1015, "David", 134000.00, LocalDate.of(2017, 9, 28)));
        employees.add(new Employee(1009, "Steve", 100000.00, LocalDate.of(2016, 5, 18)));

        System.out.println("Employees : " + employees);

        // Sort employees by Name
        Collections.sort(employees, Comparator.comparing(Employee::getName));
        System.out.println("\nEmployees (Sorted by Name) : " + employees);

        // Sort employees by Salary
        Collections.sort(employees, Comparator.comparingDouble(Employee::getSalary));
        System.out.println("\nEmployees (Sorted by Salary) : " + employees);

        // Sort employees by JoiningDate
        Collections.sort(employees, Comparator.comparing(Employee::getJoiningDate));
        System.out.println("\nEmployees (Sorted by JoiningDate) : " + employees);

        // Sort employees by Name in descending order
        Collections.sort(employees, Comparator.comparing(Employee::getName).reversed());
        System.out.println("\nEmployees (Sorted by Name in descending order) : " + employees);

        // Chaining multiple Comparators
        // Sort by Salary. If Salary is same then sort by Name
        Collections.sort(employees, Comparator.comparingDouble(Employee::getSalary)
                                    .thenComparing(Employee::getName));
        System.out.println("\nEmployees (Sorted by Salary and Name) : " + employees);
    }
}
Output:
Employees : [Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19}, 
Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28},
Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18}]

Employees (Sorted by Name) : 
[Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19},
 Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}, 
Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
 Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18}]

Employees (Sorted by Salary) : 
[Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19}, 
Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
 Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18}, 
Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}]

Employees (Sorted by JoiningDate) : 
[Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10}, 
Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18},
 Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19}, 
Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}]

Employees (Sorted by Name in descending order) : 
[Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18},
 Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
 Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}, 
Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19}]

Employees (Sorted by Salary and Name) : 
[Employee{id=1004, name='Chris', salary=95000.5, joiningDate=2017-03-19},
 Employee{id=1010, name='Rajeev', salary=100000.0, joiningDate=2010-07-10},
 Employee{id=1009, name='Steve', salary=100000.0, joiningDate=2016-05-18}, 
Employee{id=1015, name='David', salary=134000.0, joiningDate=2017-09-28}]


Comments