I usually tend to write about certain gotchas and weird Android issues, so if you expect yet another rant, I have a surprise for you – today, I’m going to write about a piece of code I’m very fond of.
As you might have noticed, I’m a big fan of Guava. One of the classes I extensively use is ComparisonChain
, which lets you turn this:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Into this:
1 2 3 4 5 6 7 8 |
|
When I first saw this API I was a bit worried about performance, because this code is supposed to be used in Comparator
s, which are executed multiple times during Collection
sorting, and it looks like it could allocate a lot of objects. So I looked at the source code and I was enlightened.
ComparisonChain is an abstract class with few versions of compare
method returning ComparisonChain object:
1 2 3 4 5 6 7 8 |
|
To get the result of comparison you call another abstract method:
1
|
|
The trick is, there are only two implementations and three instances of ComparisonChain: anonymous ACTIVE
, and LESS
and GREATER
instances of InactiveComparisonChain.
ACTIVE
instance is the one you get from ComparisonChain.start()
call. Various compare
methods in ACTIVE
instance perform comparison on supplied arguments, and depending on result return ACTIVE
, LESS
or GREATER
object. Calling result
on ACTIVE
ComparisonChain yields 0.
InactiveComparisonChain’s instances – LESS
and GREATER
– do not perform any comparisons and return themselves – if you got this object, it means that earlier comparison already established the result. The role of this object is just to forward result
call to appropriate instance. LESS.result()
returns -1 and GREATER.result()
+1.
The whole class is elegant, provide beautiful API for a common task and the implementation is very efficient. The world needs more code like this.