Comparable and Comparator

Basic Java
≈ 2 min read

When objects need an order

Numbers and strings already have an obvious order, but for custom objects Java cannot guess what should count as “smaller” or “larger.” The same object might be compared by name, price, date, or any other property. Comparable and Comparator are used to describe ordering.

Comparable: the natural order of a class

If a class has one primary, natural way to be ordered, it can implement Comparable<T> and the compareTo() method.

class Level implements Comparable<Level> {
    private final int value;

    Level(int value) {
        this.value = value;
    }

    @Override
    public int compareTo(Level other) {
        return Integer.compare(value, other.value);
    }
}

A comparison result below zero means “this object comes before,” zero means the same position in the ordering, and a result above zero means “this object comes after.” You do not need to return exactly -1, 0, or 1: the sign of the result is what matters.

Comparator: a separate comparison rule

When there are several useful orderings or the class cannot be changed, the rule is moved into a Comparator<T>.

class LengthComparator implements Comparator<String> {
    @Override
    public int compare(String left, String right) {
        return Integer.compare(left.length(), right.length());
    }
}

List<String> names = new ArrayList<>(List.of("Bob", "Alexander", "Ann"));
names.sort(new LengthComparator());

Now the strings are sorted by length, while their own natural ordering remains alphabetical. This lets you keep several independent comparison rules for one type.

Natural and reverse order

For types that already implement Comparable, the standard library provides ready-made comparators.

List<Integer> numbers = new ArrayList<>(List.of(3, 1, 2));

numbers.sort(Comparator.naturalOrder());
numbers.sort(Comparator.reverseOrder());
Zero in a comparison means “equal from the ordering point of view.” If a class's natural order contradicts its equals(), some structures and algorithms may behave unexpectedly. Such a mismatch should be deliberate.