Monday, October 11, 2010

Writing more elegant comparison logic with Guava's Ordering

One of the essential interfaces to define object ordering in Java is Comparator<T>. The contract is rather straightforward:
int compare(T o1, T o2): Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
This simplicity can be deceiving: implementing a correct and readable comparator logic can be quite tricky. There are many common pitfalls that one should be aware of, and failure to do so may lead to subtle bugs. Often we also see complicated (and therefore error-prone) comparators that implement various additional rules (e.g. null handling and/or tie breaking) that obfuscates the big picture logic. Moreover, even the simplest and most straightforward comparator often duplicates code on the two objects being compared.

One of the better solutions to solve all of these problems is Ordering<T> from Guava (a strictly compatible superset of the old Google Collections library). This post shows how it enables elegant implementation of various comparison patterns. An appendix also explains why the commonly seen comparison by subtraction and reverse order comparison by negation "tricks" are broken.