Java.Core.What is the difference between Comparator and Comparable?

🔗 Comparator vs Comparable

FeatureComparableComparator
Interface locationjava.lang (core package)java.util (utility package)
PurposeDefines natural ordering of a classDefines custom ordering for a class (outside the class itself)
Where to implement?In the class itself (the class “knows” how to compare itself)In a separate class (the comparison logic is external)
Method to implementint compareTo(T o)int compare(T o1, T o2)
Works withCollections like TreeSet, TreeMap, Arrays.sort() (natural order)Collections.sort() with custom logic
FlexibilityOnly one ordering (natural order)Can define multiple orderings for the same class
Example use caseEntities with a clear default order (like String, Integer)Sorting objects differently based on user needs (e.g., sort by name, or by age)

📜 Example — Using Comparable

Imagine a class Person where natural order is based on age:

class Person implements Comparable<Person> {
    String name;
    int age;

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

    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age);  // Natural order = by age
    }

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

Sorting (Natural Order – Age):

List<Person> people = List.of(new Person("Alice", 30), new Person("Bob", 25));
List<Person> sorted = new ArrayList<>(people);
Collections.sort(sorted);  // Works because Person implements Comparable

System.out.println(sorted);  // [Bob (25), Alice (30)]

📜 Example — Using Comparator

Now you want to sort by name sometimes, and by age other times. A Comparator lets you do that:

class Person {
    String name;
    int age;

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

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

// Comparator to sort by name
Comparator<Person> byName = (p1, p2) -> p1.name.compareTo(p2.name);

// Comparator to sort by age (if not using Comparable)
Comparator<Person> byAge = Comparator.comparingInt(p -> p.age);

Usage:

List<Person> people = List.of(new Person("Alice", 30), new Person("Bob", 25));
List<Person> sortedByName = new ArrayList<>(people);
Collections.sort(sortedByName, byName);  // Sort by name
System.out.println(sortedByName);  // [Alice (30), Bob (25)]

List<Person> sortedByAge = new ArrayList<>(people);
Collections.sort(sortedByAge, byAge);  // Sort by age
System.out.println(sortedByAge);  // [Bob (25), Alice (30)]

🔥 Summary Table

FeatureComparableComparator
Defines orderingInside the class itselfOutside the class (external)
FlexibilityOne orderMultiple orders (choose per sort)
Typical usageNatural sorting (like alphabetic or numeric order)Custom sorting (like by date, length, or multiple fields)
Sort methodCollections.sort(list) works directlyCollections.sort(list, comparator) needs comparator provided

⚠️ When to Use What?

CaseUse
Class has a clear natural order (like numbers, dates)Comparable
You want to sort the same class in different ways (by name, age, etc.)Comparator

🎯 Quick Tip for Interviews

✅ Always mention Comparable is in the class itself, and Comparator is outside the class.
✅ Mention Comparable is like “self-sorting,” while Comparator allows “external sorting.”
✅ You can even combine both! A class can implement Comparable for default order, but you can still create Comparators for other orderings.

This entry was posted in Без рубрики. Bookmark the permalink.