Comparator Interface
- In Java, sorting objects in custom ways is regularly fundamental, particularly when objects don’t have a natural ordering.
- Whereas the Comparable interface permits objects to characterize their common ordering, the Comparator interface gives a way to characterize outside or custom sorting logic.
- This gives developers more prominent adaptability in sorting objects based on distinctive criteria or different sorting strategies without altering the class itself.
Definition of the Comparator Interface
- The Comparator interface is part of the java.util package and is utilized to characterize a custom comparison technique for objects.
- Not at all like Comparable, which needs altering the class whose objects you need to compare, Comparator is utilized to characterize a isolated comparison mechanism for any class.
- The Comparator interface pronounces two primary methods:
public int compare(T o1, T o2);
- T o1 and T o2: These are the two objects of type T that are being compared.
- compare(T o1, T o2): This method compares two objects:
- Returns a negative numbers in case o1 is less than o2.
- Returns zero in case o1 is equal to o2.
- Returns a positive numbers in case o1 is greater than o2.
- The Comparator interface permits numerous sorting criteria, making it an excellent tool after you have to be sort objects in a variety of ways.

Types of Comparator Usage
1.Single-Criteria Comparison:
- In numerous cases, you simply require one criterion to compare objects. For occurrence, comparing Person objects by age or name.
2.Multi-Criteria Comparison:
- In case you would like to sort objects by more than one model (for example, sorting employees to begin with by compensation and after that by name), Comparator allows chaining comparison criteria.
3.Reverse Ordering:
- You’ll be able effortlessly reverse the natural ordering of objects by utilizing strategies given in Comparator, such as reversed().
4.Custom Comparisons:
- Comparator permits for executing complex comparisons based on diverse areas or custom logic, such as comparing objects based on numerous attributes or performing case-insensitive string comparisons.
Example of Using Comparator for Single-Criteria Comparison
Consider a Person class where we need to compare people based on their age. Rather than altering the Person class, we utilize a Comparator usage to compare objects externally.
import java.util.*;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name + " (" + age + " years old)";
}
}
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return Integer.compare(p1.getAge(), p2.getAge());
}
}
Here, we characterize a Person class with name and age, and we make an AgeComparator class that executes Comparator. The compare strategy compares the Person objects by age.
Sorting Using the Comparator
Presently, let’s sort a list of Person objects utilizing this Comparator.
public class Main {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
people.add(new Person("Charlie", 35));
// Sorting the list using the Comparator
Collections.sort(people, new AgeComparator());
// Printing the sorted list
for (Person p : people) {
System.out.println(p);
}
}
}
Output:
Bob (25 years old)
Alice (30 years old)
Charlie (35 years old)
In this example, the Comparator is used to sort the Person objects based on their age.
Example of Multi-Criteria Comparison with Comparator
In a few cases, sorting by a single criterion is deficiently. For occurrence, assume you wish to sort a list of employees to begin with by salary and after that by name. You’ll accomplish this with Comparator by chaining comparison logic.
class Employee {
private String name;
private double salary;
public Employee(String name, double salary) {
this.name = name;
this.salary = salary;
}
public double getSalary() {
return salary;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name + " (" + salary + ")";
}
}
class SalaryThenNameComparator implements Comparator<Employee> {
@Override
public int compare(Employee e1, Employee e2) {
// First compare by salary
int salaryComparison = Double.compare(e1.getSalary(), e2.getSalary());
// If salaries are equal, compare by name
if (salaryComparison == 0) {
return e1.getName().compareTo(e2.getName());
}
return salaryComparison;
}
}
Here, the SalaryThenNameComparator to begin with compares Representative objects by compensation. In case two workers have the same compensation, the comparator at that point compares them by name.
Using the Multi-Criteria Comparator
public class Main {
public static void main(String[] args) {
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("Alice", 50000));
employees.add(new Employee("Bob", 50000));
employees.add(new Employee("Charlie", 60000));
// Sorting the list using the multi-criteria comparator
Collections.sort(employees, new SalaryThenNameComparator());
// Printing the sorted list
for (Employee e : employees) {
System.out.println(e);
}
}
}
Output:
Alice (50000.0)
Bob (50000.0)
Charlie (60000.0)
Reverse Ordering with Comparator
- Some of the time, you’ll need to reverse the order of comparison.
- The Comparator interface gives a reversed() method that makes a difference with this:
Comparator<Employee> reversedComparator = new SalaryThenNameComparator().reversed();
- This reverses the order of the past sorting, making the higher compensations show up to begin with.