☕ Java Q31 / 105

What is Comparator vs Comparable?

AI-Powered Answer ✓ Answered

In Java, both `Comparable` and `Comparator` interfaces are used to define the order of objects. While they both provide sorting capabilities, they differ in how they achieve this and when they should be used, primarily concerning natural ordering versus custom ordering.

Comparable Interface

The Comparable interface is used to define the natural ordering of objects. It has a single method, compareTo(Object obj), which dictates how instances of the class should be ordered relative to each other. When a class implements Comparable, its objects can be sorted intrinsically without requiring external logic.

  • Defines natural or default ordering.
  • Implemented by the class itself whose objects are to be sorted.
  • Has a single method: public int compareTo(T o).
  • Modifies the class whose objects are being sorted.
  • Used for default sorting behavior (e.g., Integer, String, Date).
java
class Student implements Comparable<Student> {
    private String name;
    private int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int compareTo(Student other) {
        // Sort by age in ascending order
        return Integer.compare(this.age, other.age);
    }

    @Override
    public String toString() {
        return "Student{name='" + name + "', age=" + age + "}";
    }
}

Comparator Interface

The Comparator interface provides a way to define custom ordering for objects. It is typically implemented as a separate class or an anonymous inner class/lambda expression, allowing for multiple sorting strategies for the same object type. It has the compare(Object obj1, Object obj2) method.

  • Defines custom or alternative ordering.
  • Implemented by a separate class, anonymous class, or lambda expression.
  • Has a single method: public int compare(T o1, T o2).
  • Does not modify the class whose objects are being sorted.
  • Used when natural ordering is not suitable or multiple sorting criteria are needed.
java
import java.util.Comparator;

class StudentNameComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        // Sort by name in alphabetical order
        return s1.getName().compareTo(s2.getName());
    }
}

// Usage example (assuming Student class from above):
// List<Student> students = new ArrayList<>();
// students.add(new Student("Alice", 25));
// students.add(new Student("Bob", 22));
// Collections.sort(students, new StudentNameComparator());

Key Differences

FeatureComparableComparator
PurposeDefines natural/default sorting order.Defines custom/alternative sorting orders.
ImplementationImplemented by the class whose objects are being sorted.Implemented by a separate class, anonymous class, or lambda expression.
Method`int compareTo(T obj)``int compare(T obj1, T obj2)`
ModificationModifies the class itself.Does not modify the class.
Package`java.lang``java.util`
Multiple SortsOnly one natural sort order possible.Multiple custom sort orders possible.

When to Use Which?

  • Use Comparable when you want to define a single, default sorting order for the objects of a class.
  • Use Comparable when you have control over the class's source code and can modify it to implement the interface.
  • Use Comparator when you need multiple ways to sort a collection of objects.
  • Use Comparator when you don't have control over the class's source code (e.g., sorting objects from a third-party library).
  • Use Comparator when the class already implements Comparable, but you need a different sorting criterion.