Java Collections + Sorting

What is the difference between Comparable and Comparator?

Comparable defines an object's natural ordering (comparison with equals method) inside the class. Comparator defines external sorting strategies, which lets the same objects be sorted in multiple ways.

CollectionsSortingCore Java

The Real Difference

Comparable says:
“I know my own natural ordering.”

Comparator says:
“I can sort these objects differently depending on context.”

The Mental Model

Comparable

Sorting logic lives INSIDE the class

class Employee
implements Comparable<Employee>

The object itself defines its “default” or “natural” ordering.

Comparator

Sorting logic lives OUTSIDE the class

Comparator<Employee>

Different comparators can sort the same objects in different ways.

Comparable Example

Comparable is useful when a class has one obvious natural ordering.

java
public class Employee implements Comparable<Employee> {

    private String name;
    private int salary;

    @Override
    public int compareTo(Employee other) {
        return Integer.compare(this.salary, other.salary);
    }
}

Now Java knows how Employees should normally be sorted.

java
Collections.sort(employees);

Why Comparator Exists

Imagine Employees can be sorted by:

  • salary
  • name
  • age
  • performance rating
  • hire date

One class cannot realistically have five “natural” orderings.

Comparable gives you ONE default ordering.
Comparator allows MANY different sorting strategies.

Comparator Example

java
Comparator<Employee> byName =
    (a, b) -> a.getName().compareTo(b.getName());

// by salary ascending
Comparator<Employee> bySalary =
    (a, b) -> Integer.compare(
        a.getSalary(),
        b.getSalary()
    );

Now the same Employee objects can be sorted differently depending on what the application needs.

java
employees.sort(byName);

employees.sort(bySalary);

Modern Comparator Style

Modern Java usually uses Comparator utility methods instead of writing compare() manually everywhere.

java
Comparator<Employee> bySalary =
    Comparator.comparing(Employee::getSalary);

Comparator<Employee> byName =
    Comparator.comparing(Employee::getName);

Comparator Chaining

One of Comparator's biggest advantages is composition.

java
Comparator<Employee> comparator =
    Comparator
        .comparing(Employee::getSalary)
        .thenComparing(Employee::getName);

This means:

  • sort by salary first
  • if salaries match, sort by name

Common Interview Trap

Comparable modifies the class design itself.
Comparator keeps sorting logic external and more flexible.

Interviewers often want to see whether you understand the design tradeoff, not just the syntax.

Another Common Trap

Many candidates write:

java
return this.salary - other.salary;

This can overflow for large numbers.

Prefer:

java
return Integer.compare(this.salary, other.salary);

When Would You Use Each?

Use Comparable When

  • The class has one obvious natural ordering
  • You want default sorting behavior
  • The ordering belongs conceptually to the class itself

Use Comparator When

  • You need multiple sorting strategies
  • You cannot modify the original class
  • You want sorting logic separate from domain logic

Final Takeaway

Comparable is the object's built-in default ordering.
Comparator is an external sorting strategy.

Comparable gives simplicity.
Comparator gives flexibility.