liveBook · Manning

compareTo method

As explained in 100 Java Mistakes and How to Avoid Them

The compareTo method is the Comparable interface method that compares the receiver with another object and returns a negative, zero, or positive integer.

compareTo defines an object's natural order through Comparable. Its result is negative, zero, or positive when the receiver is respectively smaller than, equal to, or greater than another object. The exact nonzero value is not meaningful: callers must test its sign, not assume that every implementation returns -1 or 1. Sorting algorithms and ordered data structures depend on this contract, so a plausible-looking implementation can cause failures far from the comparison code. section 7.0 section 7.9

A valid implementation is antisymmetric and transitive. Reversing operands must reverse the result's sign, comparing an object with itself must return 0, and comparisons that report equality must behave identically relative to every third object. Returning -1 for two equal boolean wrappers, for example, says that an object is smaller than itself. Such errors can survive simple tests before breaking sorting or ordered-set behavior. section 7.10 section 7.11

class BoolObj implements Comparable<BoolObj> {
  final boolean b;

  BoolObj(boolean b) { this.b = b; }

  @Override
  public int compareTo(BoolObj o) {
    return b && !o.b ? 1 : -1;
  }
}

This compact implementation distinguishes true from false but never returns 0. Comparing two wrappers with the same value therefore violates the Comparable contract; test equal operands as well as opposite ones. section 7.10

Implement natural order defensively:

  • Return 0 when all ordering keys are equal. For a boolean key, use Boolean.compare rather than hand-written branches. section 7.10
  • Never subtract integer fields to compare them. Overflow can reverse an ordering and violate transitivity; use Integer.compare instead. section 7.11
  • Compare multi-field objects as an ordered sequence of keys, stopping at the first difference. section 7.13
  • Handle nullable keys as an ordering key too, or delegate to a comparator using nullsFirst or nullsLast. section 7.10 section 7.13
  • Prefer Comparator.comparing and thenComparing, or a delegated comparator, when they make the key sequence clearer and reduce manual branches. section 7.13 section 7.15

Compare numeric fields without overflow

Avoid `return i - other.i;`: large values of opposite signs can overflow and make a larger value appear smaller. Use `return Integer.compare(i, other.i);`. For several keys, compare the first key; only if it is equal, compare the next. This preserves the intended lexicographic order and avoids special-case branches that forget equal operands. section 7.11 section 7.13

compareTo is not interchangeable with equals. BigDecimal.compareTo returns 0 for numerically equal values regardless of scale, whereas BigDecimal.equals also compares scale. Conversely, StringBuilder can compare content through compareTo while retaining identity-based equals and hashCode. Choose the comparison relation required by the operation, and avoid mutating keys held in sets or maps when their comparison behavior may be used. section 7.4 section 8.6

A malformed comparison method may trigger `IllegalArgumentException` during sorting, but it can also silently produce incorrect order or make ordered collections fail to find elements. Static analysis and tests help, yet focused tests should include equal values, reversed operands, triples that exercise transitivity, null cases when supported, and extreme numeric values. section 7.11 section 7.9

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Details Comparable's contract, flawed implementations, overflow, multi-key ordering, and null handling without deriving library internals.
Examples
Uses boolean and integer wrappers, Person, Connection, nullable User, BigDecimal values, and mutable StringBuilder keys.
What it assumes
Assumes Java object comparison and implements Comparable through focused contract and API examples.
What you can do after
Build it from scratch or delegate safely to comparison utilities while preserving ordering contracts.
How it connects
Connects Comparable with Comparator, equals, hashCode, Arrays.sort, TreeSet, HashMap, and BigDecimal.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Java Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.