java – Comparator.reversed()不使用lambda编译

我有一些列表与一些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
这是编译器类型推断机制的弱点。为了推断λ中的u的类型,需要建立lambda的目标类型。这是如下实现的。 userList.sort()期望类型Comparator< User>的参数。在第一行中,Comparator.comparing()需要返回Comparator< User&gt ;.这意味着Comparator.comparing()需要一个接受User参数的函数。因此,在第一行的lambda中,u必须是User类型,一切正常。 在第二和第三行中,目标打字由于对inverted()的调用的存在而中断。我不完全确定为什么; reverse()的接收器和返回类型是比较器< T>所以它似乎目标类型应该传播回接收器,但它不是。 (像我说的,这是一个弱点。)

在第二行中,方法引用提供填充此间隙的附加类型信息。这个信息不在第三行,所以编译器推断u是Object(最后的推理回退),失败。

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

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

在将来的版本中,可能会增强编译器以覆盖此情况。

http://stackoverflow.com/questions/25172595/comparator-reversed-not-compiles-using-lambda

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:java – Comparator.reversed()不使用lambda编译