Reputation: 852
Is the comparison chain in guava not supposed to evaluate the compares lazily ? In the below code the NullComparator (apache) would return a non-zero value , should the chain not terminate ?
From the docs : the ComparisonChain implementation stops calling its inputs' compareTo and compare methods as soon as one of them returns a nonzero result
String x = null;
String y = "y";
ComparisonChain.start().compare(x,y, new NullComparator(false)).
compare(x.getBytes().toString(), y.getBytes().toString()).result();
note: the above was just an example . maybe this would be the better example
ComparisonChain.start().compare(x,y, new NullComparator(false)).
compare(x.getBytes(), y.getBytes(), UnsignedBytes.lexicographicalComparator()).result();
Upvotes: 2
Views: 1060
Reputation: 12922
Nothing can stop Java from evaluating the arguments to compare()
, even if the method does nothing. x.getBytes()
will throw an NPE because x
is null
.
Perhaps this would work?
return Ordering.onResultOf(new Function<String, String>() {
@Override
public String apply(String input) {
return input.getBytes().toString();
}
})
.nullsFirst()
.compare(x, y);
Keep in mind though that input.getBytes().toString()
is likely to not make very much sense to sort by (it will look like [B@35c41b
).
Upvotes: 5
Reputation: 11959
That's because what is lazy is the call to compare, not the call to x.getBytes(), hence the NPE ! ie:
ComparisonChain.start()
.compare(x,y, new NullComparator(false))
.compare(x.getBytes().toString(), y.getBytes().toString()) // <-- tries to invoke compare with two objects
.result();
You should try with a Comparator, which like this :
ComparisonChain.start()
.compare(x,y, new NullComparator(false))
.compare(x, y, new Comparator<String>() {
int compare(String a, String b) {
return a.getBytes().toString().compareTo(b.getBytes().toString());
}
})
.result();
Or with Java 8 :
ComparisonChain.start()
.compare(x,y, new NullComparator(false))
.compare(x, y, (a, b) -> a.getBytes().toString().compareTo(b.getBytes().toString()))
.result();
Note that, comparing getBytes().toString()
in real situations might not be a good idea...
Upvotes: 3