Comparator reverse string java 8编译错误

问题描述 投票:0回答:1

这里是代码片段,它在 java 8 中的第 2 行抛出了有线编译错误。

   List<Employee> employees = getEmployees();
   /*Line no:2*/  Comparator<String> comparator = ((emp1, emp2) -> emp1.compareTo(emp2)).reversed();   // ERROR  The target type of this expression must be a functional interface
   return employees.stream().map(emp -> emp.getName()).sorted(comparator)
                .collect(Collectors.toList());

但是相同的代码在第 3 行正确编译和运行

List<Employee> employees = getEmployees();
Comparator<String> comparator = ((emp1, emp2) -> emp1.compareTo(emp2));
/* Line no:3 */  comparator = comparator.reversed(); // NO ERROR GENERATED
return employees.stream().map(emp -> emp.getName()).sorted(comparator)
                .collect(Collectors.toList());

有人可以向我解释幕后发生的事情以及为什么会出现此错误吗?

java java-8 stream functional-interface
1个回答
1
投票

lambda 只是一种更简洁的方式来生成功能接口的实现。它只能在清楚 lambda 应该符合什么类型的情况下使用。在表达式

((emp1, emp2) -> emp1.compareTo(emp2)).reversed()
的上下文中,lambda 不会立即被分配给变量或传递给函数(这将允许推断其类型),而是更大表达式的子表达式。这导致了问题。

您可以通过强制转换使类型显式:

var comparator = ((Comparator<String>)(emp1, emp2) -> emp1.compareTo(emp2)).reversed();

来自Java教程

为了确定 lambda 表达式的类型,Java 编译器使用找到 lambda 表达式的上下文或情况的目标类型。因此,您只能在 Java 编译器可以确定目标类型的情况下使用 lambda 表达式:
  • 变量声明
  • 作业
  • 退货单
  • 数组初始化器
  • 方法或构造函数参数
  • Lambda 表达式体
  • 条件表达式,
    ?:
  • 演员表
© www.soinside.com 2019 - 2024. All rights reserved.