Additional convenience methods on Comparator{s}

Michael Hixson michael.hixson at gmail.com
Thu Jan 24 20:34:28 PST 2013


A small followup...

Two downsides of my proposed null{First,Last} methods are:

1) They produce comparators that are inconsistent with equals.
2) People might misinterpret them to mean "nulls first/last then
natural order", which they're not.

So instead of what I initially proposed, maybe these forms are better:

public static <T> Comparator<T> nullsFirstThen(Comparator<? super T>
comparator);
public static <T> Comparator<T> nullsLastThen(Comparator<? super T> comparator);

Then the original example becomes:

Collections.sort(
    people,
    comparing(Person::getLastName, CASE_INSENSITIVE_ORDER)
        .thenComparing(
            Person::getEmailAddress,
            nullsLastThen(CASE_INSENSITIVE_ORDER)));

-Michael

On Thu, Jan 24, 2013 at 7:09 PM, Michael Hixson
<michael.hixson at gmail.com> wrote:
> I have a suggestion for a few new convenience methods on
> Comparator{s}.  They're meant to address the use case of: sort the
> elements by some field, but not using the natural ordering of that
> field's type (if it even has a natural ordering).  Most commonly,
> that'll probably be sorting by a string field ignoring case.  In fact
> I can't think of a single instance where I wanted to sort strings
> while *not* ignoring case.
>
> Admittedly, the functionality I'm about to suggest could be achieved
> using my own helper methods; if they aren't in the JDK, they still
> work (save for some potentially awkward English in one case).  But I
> think they're on par with the usefulness of the other convenience
> methods in Comparator{s}.
>
>
> On j.u.Comparator:
>
> default <U> Comparator<T> thenComparing(
>     Function<? super T, ? extends U> keyExtractor,
>     Comparator<? super U> keyComparator);
>
> On j.u.Comparators:
>
> public static <T, U> Comparator<T> comparing(
>     Function<? super T, ? extends U> keyExtractor,
>     Comparator<? super U> keyComparator);
> public static <T> Comparator<T> nullsFirst();
> public static <T> Comparator<T> nullsLast();
>
>
> Example usage:
>
> // Sort a list of people by:
> //  1) Last name, ignoring case
> //  2) Email address, with no email (null) last, ignoring case
> List<Person> people = ...
> Collections.sort(
>     people,
>     comparing(Person::getLastName, CASE_INSENSITIVE_ORDER)
>         .thenComparing(
>             Person::getEmailAddress,
>             nullsLast().thenComparing(CASE_INSENSITIVE_ORDER)));
>
>
> Without these methods in the JDK, specifically
> Comparator.thenComparing(Function, Comparator), the "awkward English"
> I referred to would be:
>     .thenComparing(comparing(Person::getEmailAddress, ...))
>
> For what it's worth, with these helper methods, I was able to remove
> all dependencies on Guava's Ordering and ComparisonChain--their fluent
> Comparator utilities--from my application.
>
> -Michael


More information about the lambda-libs-spec-comments mailing list