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}]
More Examples
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class JLEComparatorExample {
public static void main(String[] args) {
List<Person> listOfPerson = new ArrayList<Person>();
listOfPerson.add(new Person("abc", 27));
listOfPerson.add(new Person("mno", 26));
listOfPerson.add(new Person("pqr", 28));
listOfPerson.add(new Person("xyz", 27));
// Without lambda expression.
// Sort list by age
Comparator<Person> comparator = new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
};
Collections.sort(listOfPerson, comparator);
System.out.println(" sort persons by age in ascending order");
for (Person person : listOfPerson) {
System.out.println(" Person name : " + person.getName());
}
// Witht lambda expression.
// Sort list by age
Collections.sort(listOfPerson, (Person o1, Person o2) -> {
return o1.getAge() - o2.getAge();
});
// Use forEach method added in java 8
System.out.println(" sort persons by age in ascending order");
listOfPerson.forEach(
(person) -> System.out.println(" Person name : " + person.getName()));
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
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;
}
}
Related Collections Framework API Guides
- Collections Framework - ArrayList Class
- Collections Framework - LinkedList Class
- Collections Framework - CopyOnWriteArrayList
- Collections Framework - HashSet Class
- Collections Framework - LinkedHashSet Class
- Collections Framework - TreeSet Class
- Collections Framework - CopyOnWriteArraySet
- Collections Framework - EnumSet
- Collections Framework - HashMap Class
- Collections Framework - LinkedHashMap Class
- Collections Framework - TreeMap class
- Collections Framework - EnumMap
- Collections Framework - WeakHashMap
- Collections Framework - IdentityHashMap
Free Spring Boot Tutorial | Full In-depth Course | Learn Spring Boot in 10 Hours
Watch this course on YouTube at Spring Boot Tutorial | Fee 10 Hours Full Course