guava
guava copied to clipboard
Document that `ComparisonChain` is mostly obsolete
There are few if any reasons to use ComparisonChain
if you are using a version of Java that has lambdas and Comparator.comparing
. The example usage in the current API documentation is this:
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(this.aString, that.aString)
.compare(this.anInt, that.anInt)
.compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
.result();
}
If you have Comparator.comparing
and the rest, you'll want to do something like this:
private static final Comparator<Foo> COMPARATOR =
comparing((Foo foo) -> foo.aString)
.thenComparing((Foo foo) -> foo.anInt)
.thenComparing((Foo foo) -> foo.anEnum, nullsLast(naturalOrder()));
Then use COMPARATOR
, or just expose it as a public field. Here comparing
, nullsLast
, and naturalOrder
are all static-imported from Comparator
. The example could use method references if the comparison was in terms of aString()
rather than aString
.
Similarly compareFalseFirst(this.aBool, that.aBool)
can be replaced by .thenComparing((Foo foo) -> foo.aBool, falseFirst())
, using com.google.common.primitives.Boolean.falseFirst
. (Or you can just leave it out, since the natural order for Boolean
comparison already sorts false
first.)
Using comparing
etc is much better than ComparisonChain
for a couple of reasons:
- It avoids the annoying repetition between
this
andthat
((this.aString, that.aString)
). - It genuinely short-circuits: as soon as one of the comparisons is non-zero, the rest of the chain just propagates that non-zero value.
Meanwhile ComparisonChain
must evaluate the parameters of all of the remaining .compare(this.x, that.x)
calls, even when the comparison result is already known. This has led people to ask at least twice (#2160, #3584) for an alternative that delays the computation of these parameters when it is expensive. We already have that alternative and it is Comparator.comparing
.
So I think we should, at least, document in ComparisonChain
that the Comparator
methods are preferable and show the rewritten example above. Maybe we should also deprecate the class.