NateH06
NateH06

Reputation: 3574

Replaced a custom Comparator with Comparator.comparing() - why does this work?

I have a List<Meeting> and Meeting is as follows:

public class Meeting {
    private Calendar date;
    public Calendar getDate() {
      return this.date
    }
}

In originally had a Custom lambda comparator in the .sorted() portion of a stream (myMeetingList is a List<Meeting>) :

return myMeetingList.parallelStream()
                    .filter(m -> m.getContacts().contains(contact))
                    .sorted((m1,m2) -> m1.getDate().compareTo(m2.getDate()))
                    .collect(Collectors.toList());

I stumbled across something completely by accident. I think it works, but I have no idea why. Instead of creating the custom Comparator I replaced it with what looks like a static method reference:

return myMeetingList.parallelStream()
                    .filter(m -> m.getContacts().contains(contact))
                    .sorted(Comparator.comparing(Meeting::getDate))
                    .collect(Collectors.toList());

I believe it works, but I honestly don't know why. The JavaDoc for one of the implementations of Comparator.comparing() shows

static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor)

but have searched a few blogs and read through the doc a few times, and I'm having a hard time deciphering that. Reading my actual code makes sense, but I couldn't have derived that on my own without checking the example in the JavaDoc. Anyone have any ideas on how to better explain that?

Upvotes: 0

Views: 1938

Answers (1)

greg-449
greg-449

Reputation: 111142

The code in Comparator.comparing is just:

Objects.requireNonNull(keyExtractor);

return (Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));

The first line is just a check that the parameter is not null.

The second line returns a Comparator which just calls the keyExtractor function to get the values to compare and uses their compareTo method to do the compare. The generics in the declaration of comparing ensures that keyExtractor must implement Comparable.

In your case the Meeting::getDate method reference will produce a keyExtractor function which just calls the getDate method, so

keyExtractor.apply(c1)

will execute

c1.getDate()

So the end result is essentially the same as your original code.

Upvotes: 2

Related Questions