Java Lambdas and Closures

2022-09-02 09:12:49

我听说lambdas即将出现在你附近的Java(J8)上。我在一些博客上找到了它们的外观示例:

SoccerService soccerService = (teamA, teamB) -> {
    SoccerResult result = null;
    if (teamA == teamB) {
        result = SoccerResult.DRAW;
    }
    else if(teamA < teamB) {
        result = SoccerResult.LOST;
    }
    else {
        result = SoccerResult.WON;
    }

    return result;
};

所以马上就要开始了:

  • 在哪里键入?或者它们不是(就像某种奇怪的泛型形式)?teamAteamB
  • lambda是一种闭包还是相反?
  • 与典型的匿名函数相比,这将给我带来什么好处?

答案 1

Lambda 表达式只是实现目标接口的语法糖,这意味着您将通过 lambda 表达式在接口中实现特定方法。编译器可以推断接口中参数的类型,这就是为什么您不需要在 lambda 表达式中显式定义它们的原因。

例如:

Comparator<String> c = (s1, s2) -> s1.compareToIgnoreCase(s2);

在此表达式中,lambda 表达式显然实现了字符串的 a,因此,这意味着 lambda 表达式是用于实现 的语法糖。Comparatorcompare(String, String)

因此,编译器可以安全地假定 和 的类型为 。s1s2String

您的目标接口类型提供编译器确定 lambda 参数的实际类型所需的所有信息。

Oracle Corportion的Java语言架构师Briant Goetz发表了几篇关于JDK 8 Lambdas正在进行的工作的文章。我相信你的问题的答案就在那里:

第二篇文章介绍了如何在字节码级别实现 lambda 表达式,并可能有助于您深入研究第二个问题的详细信息。


答案 2

有关示例的完整版本,请参阅此页面(但是,相关部分如下所示)。

这些类型是从 SoccerService 接口和 SoccerResult 枚举推断出来的,未显示在代码段中:

enum SoccerResult{
    WON, LOST, DRAW
}

interface SoccerService {
    SoccerResult getSoccerResult(Integer teamA, Integer teamB);
}

(lambdas 与标准匿名相比)的好处只是减少了冗长:

(x, y) => x + y

与类似的东西相比:

new Adder()
{
  public int add(int x, int y)
  {
    return x + y;
  }
}

有关闭包和 lambda 之间的区别,请参阅此问题