当前位置: 首页 > 面试题库 >

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

都博裕
2023-03-14
问题内容

我有一个包含一些User对象的列表,我正在尝试对列表进行排序,但是只能使用方法引用来工作,对于lambda表达式,编译器会给出错误:

List<User> userList = Arrays.asList(u1, u2, u3);
userList.sort(Comparator.comparing(u -> u.getName())); // works
userList.sort(Comparator.comparing(User::getName).reversed()); // works
userList.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 Object
1 error

问题答案:

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

在第二行和第三行中,对的调用会干扰目标类型reversed()。我不完全清楚为什么。接收器和的返回类型reversed()都是Comparator<T>如此,因此似乎应该将目标类型传播回接收器,但事实并非如此。(就像我说的那样,这是一个缺点。)

在第二行中,方法参考提供了填补此空白的其他类型信息。第三行缺少此信息,因此编译器推断u为Object(失败的推断回退),这将失败。

显然,如果可以使用方法引用,则可以使用它。有时你不能使用方法引用,例如,如果你想传递附加参数,则必须使用lambda表达式。在这种情况下,你可以在lambda中提供一个明确的参数类型:

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

在将来的发行版中,可能会增强编译器以涵盖这种情况。



 类似资料:
  • 我有一个包含一些用户对象的列表,我正在尝试对列表进行排序,但只使用方法引用,使用lambda表达式编译器会给出一个错误: 错误:

  • 问题内容: 在过去的两年中,我一直在编写Java,现在,我开始用python(另外)进行编写。 问题是,当我查看我的Python代码时,似乎有人试图将Java代码转换为python格式,但结果却很糟糕,因为- python不是Java。 关于如何摆脱“用Python编写Java”模式的任何技巧? 谢谢! 问题答案: 您可能会考虑将自己沉浸在Python范例中。最好的方法是首先了解他们的知识,然后通

  • 错误 我正在编译SimpleCompiletest.java并得到这个错误。救命啊!!!

  • 我的方法应该按字母顺序排序所有对象的姓氏,这些对象包含在一个arraylist中 Rubrica类 主要的 谢谢你的帮助。

  • 问题内容: 我正在使用的Less编译器OrangeBits和dotless1.3.0.5正在积极地进行翻译 进入 这显然是不希望的。我想知道是否有一种方法可以通知Less编译器在编译过程中实质上忽略该属性。我搜索了Less文档和两个编译器的文档,但找不到任何东西。 更少或更少的编译器是否支持此功能? 如果没有,是否有CSS扩展器呢? 问题答案: 由于,默认情况下,Less不再计算内部表达式。 原始

  • 问题内容: 我在编译代码时收到一条消息: 如何重新编译? 问题答案: 在javac的命令行上指定它: javac -Xlint:unchecked 或者,如果您使用的是Ant,请修改您的javac目标 如果您使用的是Maven,请在