The Comparator
interface in Java provides a way to order objects of user-defined classes. It allows you to define custom sorting logic outside of the class being sorted, offering flexibility and reusability. This is in contrast to the Comparable
interface, which requires implementing sorting logic within the class itself.
Understanding the Comparator Interface
The core of the Comparator
interface is the compare()
method:
public int compare(Object obj1, Object obj2);
This method compares two objects (obj1
and obj2
) and returns:
- A negative integer if
obj1
is less thanobj2
. - Zero if
obj1
is equal toobj2
. - A positive integer if
obj1
is greater thanobj2
.
By implementing the Comparator
interface and defining the compare()
method, you dictate how objects should be ordered when using sorting methods like Collections.sort()
.
How to Use Comparator
Let’s say you have a Student
class:
class Student {
int rollno;
String name;
Student(int rollno, String name) {
this.rollno = rollno;
this.name = name;
}
// ... other methods ...
}
To sort a list of Student
objects by rollno
, you would create a separate class implementing Comparator
:
class SortbyRoll implements Comparator<Student> {
public int compare(Student a, Student b) {
return a.rollno - b.rollno; // Ascending order
}
}
Then, use Collections.sort()
with your Comparator
:
List<Student> students = new ArrayList<>();
// ... add Student objects ...
Collections.sort(students, new SortbyRoll());
Lambda Expressions for Concise Comparators
Java 8 introduced lambda expressions, enabling more concise Comparator
implementations:
students.sort((s1, s2) -> Integer.compare(s1.rollno, s2.rollno)); // Ascending
This achieves the same result as the SortbyRoll
class but with fewer lines of code.
Sorting by Multiple Fields
Comparator
allows sorting by multiple fields. Suppose you want to sort students first by name and then by age (if names are the same):
class Student {
// ... previous fields ...
int age;
// ... constructor and other methods ...
}
class CustomerSortingComparator implements Comparator<Student> {
public int compare(Student s1, Student s2) {
int nameCompare = s1.name.compareTo(s2.name);
return (nameCompare == 0) ? Integer.compare(s1.age, s2.age) : nameCompare;
}
}
Collections.sort(students, new CustomerSortingComparator());
Alternatively, using method chaining with lambda expressions:
students.sort(Comparator.comparing(Student::getName).thenComparing(Student::getAge));
Comparator vs Comparable
While both Comparator
and Comparable
enable sorting, they differ in how they are implemented and their flexibility. Comparator
offers external sorting logic and supports multiple sorting orders, whereas Comparable
defines sorting logic within the class itself, allowing only one inherent sorting order. Comparator
uses the compare()
method, while Comparable
uses the compareTo()
method.
Conclusion
The Comparator
interface in Java is a powerful tool for defining custom sorting logic for objects. Its flexibility, especially with lambda expressions, makes it a preferred choice for complex sorting requirements and promotes code reusability. Understanding the differences between Comparator
and Comparable
is crucial for choosing the right approach for your sorting needs.