Mastery
Mastery/Java/C. Collections framework
T1 · high-leverage

Comparable vs Comparator

Comparable<T> (via compareTo) defines a class's single "natural" ordering, implemented by the class itself. Comparator<T> defines an external, swappable ordering, and can be composed fluently: Comparator.comparing(...).thenComparing(...), .reversed(), etc. — the idiomatic way to sort by multiple criteria without writing a manual compareTo chain.

java
import java.util.*;

List<String> names = new ArrayList<>(List.of("banana", "apple", "Cherry"));

names.sort(Comparator.naturalOrder());
System.out.println("natural order (case-sensitive, capitals sort first): " + names);

names.sort(Comparator.comparing(String::length).thenComparing(Comparator.naturalOrder()));
System.out.println("by length, then natural order as tiebreak:           " + names);

names.sort(Comparator.comparing(String::length).reversed());
System.out.println("by length descending:                                " + names);

Interview angle

Commonly tested by asking a candidate to sort a list of custom objects by multiple fields — checking fluency with Comparator.comparing().thenComparing() chains versus writing a manual, error-prone compareTo implementation by hand. It's also a decent proxy for how current someone's Java knowledge is, since the fluent Comparator API is Java 8+.

In the industry

Most real sorting requirements involve multiple criteria or context-dependent ordering, which rules out Comparable's single "natural" ordering as a complete solution — so Comparator chains are the default idiom in modern Java code. A hand-rolled multi-field compareTo with nested if statements is a code-review red flag: it's both more error-prone (easy to get the tiebreak logic subtly wrong) and less readable than the fluent equivalent.