Re: toward null-safe cookie cutter Comparators
In article <alpine.DEB.2.00.1111131750140.19917@urchin.earth.li>,
twic@urchin.earth.li says...
http://groups.google.com/group/comp.lang.java.advocacy/browse_thread/t
hread/83db33bcbd51905d#
Approaches involving nested if-elses will be more efficient, but always
strike me as rather awkward.
I have shown a number of possible snippets. Please let me know what
you
think and see if you can come up with something better - fast, terse and
comprehensible.
I personally rather like your third option:
final String aSpecies = a.species == null ? "" : a.species;
final String bSpecies = b.species == null ? "" : b.species;
return aSpecies.compareTo( bSpecies );
Looks good on first sight, but is ugly on second sight.
What if you need all nulls smaller than all empty strings?
That said I have seen a lot of client code that repeated the null-low or
null-high idiom all over the application in all possible ways, some of
them overly complicated or just plain wrong. Also, it doesn't help the
readability at all.
So I like to use the ComparatorUtils in the apache.commons project, or
create something alike, if the customer doesn't like to include the lib
and allows me to refactor the code. Just for your interest, in my coding
style that utility method would probably look something like this:
static <T> Comparator<T> nullLowComparator(final Comparator<T> delegate)
{
return new Comparator<T>(){
public int compare(final T a, final T b){
return a != null && b != null ? delegate.compare(a,b)
: a == null ? -1
: 1;
}
}
}
Once defined (or found in a library), the client code would reuse that
to avoid repeating the null-low/high idiom. I usually comment that null-
safety with an assertion:
static final Comparator<String> STRING_NATURAL_ORDER =
ComparatorUtils.nullLowComparator(new Comparator<String>(){
final int compare(final String a, final String b){
assert a != null && b != null : "Handled by NullLowComparator";
return a.compareTo(b);
}
});
Often it looks a bit slicker when used with static imports:
static final Comparator<String> STRING_NATURAL_ORDER=nullLowComparator(
new Comparator<String>(){
final int compare(final String a, final String b){
assert a != null && b != null : "Handled by NullLowComparator";
return a.compareTo(b);
}
});
Well, the ComparatorUtils already have a natural-order comparator, so,
this is just an example, usually you'd find a collator there, or a
length comparison or alike.
I have also built comparators that use other comparators in a similar
fashion:
static final Comparator<String> PERSON_BY_AGE= nullLowComparator(
new Comparator<String>(){
final int compare(final String a, final String b){
assert a != null && b != null : "Handled by NullLowComparator";
return reversedComparator(DATE_COMPARATOR)
.compare(a.getBirthday(), b.getBirthday());
}
});
Assuming "DATE_COMPARATOR" is a similar built nullsafe-comparator for
dates.
Personally I found that this is the best way to do it.
Kind regards,
Wanja
--
...Alesi's problem was that the back of the car was jumping up and down
dangerously - and I can assure you from having been teammate to
Jean Alesi and knowing what kind of cars that he can pull up with,
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]
--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---