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.
The implementation of the compare() method should return
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);
}
- 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.
Comparator interface Example 1
Let’s see how to sort a collection of Employee objects by following Employee fields:
- Sort employees by Name
- Sort employees by Salary
- Sort employees by JoiningDate
- Sort employees by Name in descending order
- Chaining multiple Comparators - Sort by Salary. If Salary is the same then sort by Name
Let's write a Java program to sort employees in ascending order by name, salary, joining date, and sort employees in descending order.
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}]
Comparator interface Example 2
Let's see one more example, sorting person objects by age using Java 8 Lambda expressions and Java 8 forEach() method.
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<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; } }
Reference
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