Java Comparator Interface

The Comparable interface that we learned in the previous guide defines a default ordering for the objects of a class. This default ordering is also called the natural ordering of the objects.
 
What if you want to sort some objects in an order other than their natural ordering? Or what if you want to sort some objects that don't implement Comparable? To do either of these things, you'll need to provide a Comparator — an object that encapsulates an ordering. Like the Comparable interface, the Comparator interface consists of a single method.
public interface Comparator<T> {
    int compare(T o1, T o2);
}
The implementation of the compare() method should return
  • a negative integer, if the first argument is less than the second,
  • zero, if the first argument is equal to the second, and
  • a positive integer, if the first argument is greater than the second.
If either of the arguments has an inappropriate type for the Comparator, the compare method throws a ClassCastException.

Comparator interface Example

Let’s see how to sort a collection of Employee objects that we defined in the previous section based on different fields by defining different Comparators.

Example 1: Sort employees by Name

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);

Example 2: Sort employees by Salary

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)));

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

Example 3: Sort employees by JoiningDate

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)));

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

Example 4: Sort employees by Name in descending order

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)));

// 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);

Example 5: Chaining multiple Comparators

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)));

// 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);

Complete Example for Reference

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}]

Related Collections Framework API Guides

Comments