所以我有一个任务,使用List
对某个Comparator
进行排序,并将lambda与stream方法一起使用,之后我必须比较使用比较器对列表进行排序所需的时间与lambda和stream组合。
我们假设我有一个Communication
类,其中包含commTime
和Client
个属性(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);
但我不知道我能做些什么。
对于我必须确定排序长度的应用程序部分,我知道如何做到这一点,所以不需要解释那部分(至少我知道如何做某事,对吧?)。
答案 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);