为了账号安全,请及时绑定邮箱和手机立即绑定

Comparator.reversed()不使用lambda进行编译

Comparator.reversed()不使用lambda进行编译

阿晨1998 2019-08-12 18:21:16
Comparator.reversed()不使用lambda进行编译我有一个包含一些User对象的列表,我正在尝试对列表进行排序,但只能使用方法引用,使用lambda表达式,编译器会给出错误:List<User> userList = Arrays.asList(u1, u2, u3);userList.sort(Comparator.comparing(u -> u.getName())); // worksuserList.sort(Comparator.comparing(User::getName).reversed()); // worksuserList.sort(Comparator.comparing(u -> u.getName()).reversed()); // Compiler error错误:com\java8\collectionapi\CollectionTest.java:35: error: cannot find symbol             userList.sort(Comparator.comparing(u -> u.getName()).reversed());                                                      ^symbol:   method getName()location: variable u of type Object1 error
查看完整描述

2 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

这是编译器类型推理机制的一个弱点。为了推断ulambda中的类型,需要建立lambda的目标类型。这完成如下。userList.sort()期待一种类型的论证Comparator<User>。在第一行,Comparator.comparing()需要返回Comparator<User>。这意味着Comparator.comparing()需要Function采用一个User参数。因此,在第一行的lambda中,u必须是类型User,一切正常。

在第二行和第三行中,目标类型由于存在调用而中断reversed()。我不完全确定为什么; 接收器和返回类型reversed()都是Comparator<T>如此,似乎目标类型应该传播回接收器,但事实并非如此。(就像我说的,这是一个弱点。)

在第二行中,方法参考提供了填补这一空白的其他类型信息。此信息是从第三行不存在,所以编译器推断uObject(不得已的推论回退),这将失败。

显然,如果你可以使用方法参考,那么这样做就可以了。有时您不能使用方法引用,例如,如果要传递其他参数,则必须使用lambda表达式。在这种情况下,您将在lambda中提供显式参数类型:

userList.sort(Comparator.comparing((User u) -> u.getName()).reversed());

可能有可能在将来的版本中增强编译器以涵盖这种情况。


查看完整回答
反对 回复 2019-08-12
?
长风秋雁

TA贡献1757条经验 获得超7个赞

您可以通过使用Comparator.comparing带有Comparator.reverseOrder()第二个参数的双参数来解决此限制:

users.sort(comparing(User::getName, reverseOrder()));


查看完整回答
反对 回复 2019-08-12
  • 2 回答
  • 0 关注
  • 2683 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号