Comparators
In real-world Java applications, data rarely stays in a default order. You often need to sort objects based on different conditions.
A Comparator in Java provides a flexible way to define custom sorting logic for objects.
Why Comparators Are Needed
By default, Java knows how to sort simple data types like numbers and strings. But when it comes to custom objects, Java needs instructions.
Comparators allow you to:
- Sort objects by different fields
- Change sorting logic without modifying the class
- Create multiple sorting strategies
Comparable vs Comparator
Before using Comparator, it is important to understand the difference.
- Comparable – defines natural ordering inside the class
- Comparator – defines external custom ordering
Comparator is preferred when multiple sorting rules are required.
Example Without Comparator
Consider a Student class.
class Student {
int id;
String name;
Student(int id, String name) {
this.id = id;
this.name = name;
}
}
Java does not know how to sort Student objects yet.
Creating a Comparator
Let us create a Comparator to sort students by name.
import java.util.Comparator;
class NameComparator implements Comparator {
public int compare(Student s1, Student s2) {
return s1.name.compareTo(s2.name);
}
}
Using Comparator with Collections
Now we apply the Comparator while sorting a list.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List students = new ArrayList<>();
students.add(new Student(3, "Charlie"));
students.add(new Student(1, "Alice"));
students.add(new Student(2, "Bob"));
Collections.sort(students, new NameComparator());
for (Student s : students) {
System.out.println(s.id + " " + s.name);
}
}
}
Sorting by Different Fields
You can easily change sorting behavior by creating another Comparator.
class IdComparator implements Comparator {
public int compare(Student s1, Student s2) {
return Integer.compare(s1.id, s2.id);
}
}
This flexibility is the biggest strength of Comparator.
Comparator Using Lambda Expression
With Java 8 and later, Comparators can be written more concisely.
Collections.sort(students, (s1, s2) -> s1.name.compareTo(s2.name));
This makes the code cleaner and easier to read.
Real-World Example
Imagine sorting products in an online store.
class Product {
String name;
double price;
Product(String name, double price) {
this.name = name;
this.price = price;
}
}
Collections.sort(products, (p1, p2) ->
Double.compare(p1.price, p2.price));
Users can sort products by price, name, or rating dynamically.
When to Use Comparator
- When multiple sorting strategies are required
- When you cannot modify the original class
- When sorting logic changes frequently
Key Takeaways
- Comparator provides custom sorting logic
- Sorting rules are kept separate from data
- Essential for real-world Java applications
- Works seamlessly with collections
In the next lesson, we will explore Collection Algorithms and learn advanced operations on collections.