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 Comparators, 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.