用Comparator.comparing()替换了自定义Comparator - 为什么这样做?

时间:2017-01-05 03:34:14

标签: lambda java-8 java-stream comparator

我有一个List<Meeting>,会议如下:

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

最初在流的.sorted()部分中有一个自定义lambda比较器(myMeetingListList<Meeting>):

return myMeetingList.parallelStream()
                    .filter(m -> m.getContacts().contains(contact))
                    .sorted((m1,m2) -> m1.getDate().compareTo(m2.getDate()))
                    .collect(Collectors.toList());
我完全意外地偶然发现了一些事情。我认为它有效,但我不知道为什么。我没有创建自定义Comparator,而是将其替换为静态方法引用:

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

我相信它有效,但老实说,我不知道为什么。 Comparator.comparing()的其中一个实现的JavaDoc显示

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

但是已经搜索了几篇博客并阅读了几次文档,我很难解读它。阅读我的实际代码是有道理的,但我无法在不检查JavaDoc中的示例的情况下自行派生。任何人对如何更好地解释这个有任何想法?

1 个答案:

答案 0 :(得分:2)

Comparator.comparing中的代码只是:

Objects.requireNonNull(keyExtractor);

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

第一行只是检查参数是否为空。

第二行返回Comparator,只调用keyExtractor函数获取要比较的值,并使用其compareTo方法进行比较。声明comparing中的泛型可确保keyExtractor必须实施Comparable

在您的情况下,Meeting::getDate方法引用将生成keyExtractor函数,该函数只调用getDate方法,因此

keyExtractor.apply(c1)

将执行

c1.getDate()

因此最终结果与原始代码基本相同。