如何使用lambda和流方法

时间:2017-07-18 21:30:43

标签: java sorting lambda java-stream

所以我有一个任务,使用List对某个Comparator进行排序,并将lambda与stream方法一起使用,之后我必须比较使用比较器对列表进行排序所需的时间与lambda和stream组合。

我们假设我有一个Communication类,其中包含commTimeClient个属性(Client有一个getSurname方法)。 现在,在应用程序中,我必须使用上述两种方法对communications列表进行排序。我已经使用Comparator完成了一个,但我在使用lambda和stream方法时遇到了麻烦。

我有这样的事情:

Collections.sort(communications, (comm1, comm2) -> comm1.getCommTime().compareTo(comm2.getCommTime()));

这将在if语句下(如果时间不相等),但如果它相等,我必须通过比较通信中客户的姓氏来对列表进行排序。我不知道如何做到这一点,更准确地说 - 我不知道如何从通信本身到达客户的姓氏。

我不能这样做:

Function<Communication, LocalDateTime> byTime = Communication::getCommTime;
Function<Communication, String> bySurname = Communication.getClient()::getSurname;
Comparator<Communication> byTimeAndSurname = Comparator.comparing(byTime).thenComparing(bySurname);

communications.stream().sorted(byTimeAndSurname);

但我不知道我能做些什么。

对于我必须确定排序长度的应用程序部分,我知道如何做到这一点,所以不需要解释那部分(至少我知道如何做某事,对吧?)。

1 个答案:

答案 0 :(得分:2)

Communication.getClient()::getSurname;几乎没有问题。由于.getClient()不是静态的,因此您无法将其用作Communication.getClient()。另一个问题是它会为一个对象创建方法引用,该对象在创建此方法引用时将从getClient()返回。

最简单的方法是使用lambda表达式,如

Function<Communication, String> bySurname = com -> com.getClient().getSurname();

BTW communications.stream().sorted(byTimeAndSurname);对流进行排序,而不对其来源(communications)进行排序。如果您想对communications进行排序,则应使用

Collections.sort(communications, byTimeAndSurname);

通过A->C实现A->B->C映射的其他方式是使用

someAToBFunction.andThen(someBToCFunction)
                 ^^^^^^^

documentation)。在你的情况下你可以写

Function<Communication, Client> byClient = Communication::getClient;
Function<Communication, String> bySurname = byClient.andThen(Client::getSurname);

或(uglier)“one-liner”:

Function<Communication, String> bySurname = 
              ((Function<Communication, Client>)Communication::getClient)
              .andThen(Client::getSurname);