Difference Between Comparable and Comparator
Comparable and Comparator are both interfaces used to sort objects in Java. Comparable defines the natural order of a class, written inside the class itself. Comparator defines other orders, written outside the class. In this lesson, you will learn all the differences between them through one example that uses both.
Example: Using Both Together
Let's see an example of a Student class that is naturally sorted by roll number but can also be sorted by name and by marks.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Student implements Comparable<Student> {
int roll;
String name;
int marks;
Student(int roll, String name, int marks) {
this.roll = roll;
this.name = name;
this.marks = marks;
}
@Override
public int compareTo(Student other) {
return Integer.compare(roll, other.roll);
}
@Override
public String toString() {
return roll + ":" + name + ":" + marks;
}
}
public class BothOrders {
public static void main(String[] args) {
List<Student> list = new ArrayList<>(List.of(
new Student(3, "Navika", 91),
new Student(1, "Srihitha", 78),
new Student(2, "Advitha", 85)));
Collections.sort(list);
System.out.println("By roll (Comparable): " + list);
list.sort(Comparator.comparing(s -> s.name));
System.out.println("By name (Comparator): " + list);
list.sort(Comparator.comparingInt((Student s) -> s.marks).reversed());
System.out.println("By marks (Comparator): " + list);
}
}By roll (Comparable): [1:Srihitha:78, 2:Advitha:85, 3:Navika:91]
By name (Comparator): [2:Advitha:85, 3:Navika:91, 1:Srihitha:78]
By marks (Comparator): [3:Navika:91, 2:Advitha:85, 1:Srihitha:78]Explanation: Collections.sort(list) with no comparator uses compareTo, the natural order by roll number. The two comparators sort the same list by name and by marks, without changing the Student class. Note the (Student s) type in the last line: reversed() needs it because Java can't infer the type through a chained call.
Differences Between Comparable and Comparator
| Comparable | Comparator | |
|---|---|---|
| Purpose | Defines the natural order | Defines custom orders |
| Package | java.lang | java.util |
| Method | int compareTo(T other) | int compare(T a, T b) |
| Where it is written | Inside the class being sorted | Outside, in a separate class or lambda |
| Number of orders | One per class | Many |
| Changes the class? | Yes, the class must implement it | No |
| Works with classes you can't edit | No | Yes |
| Used by | Collections.sort(list), new TreeSet<>() | list.sort(c), new TreeSet<>(c) |
| Helper methods | None | comparing, thenComparing, reversed... |
When to Use Each
Common Mistakes
Implementing Comparable for an order that isn't obvious, such as students by marks. Readers can't guess it; use a named comparator.
Calling Collections.sort(list) on a class without Comparable. It doesn't compile; pass a comparator.
Interview Corner
What is the difference between Comparable and Comparator?
Comparable (in java.lang) is implemented by the class itself and defines its single natural ordering through compareTo(T). Comparator (in java.util) is a separate object, usually a lambda, that defines an ordering through compare(T, T); you can have many comparators for one class, and you can use them with classes you can't modify. Sorting methods use Comparable when no comparator is given.
Practice
- Easy: Make an
EmployeeclassComparableby ID, then sort a list by salary with a comparator. - Harder: Create a
TreeSet<Employee>using a comparator by name. Explain why adding two employees with the same name keeps only one.
Key Takeaways
Was this tutorial helpful?