在Java中使用lambda表达式有任何运行时优势吗?

Amo*_*til 5 java lambda java-8

我正在阅读有关Java 8中提供的lambda表达式的两个博客和答案。

我无法弄清楚,单位lambda表达式是否对运行时有好处?

我从不同的来源复制了以下文本,这使我感到非常困惑。

一个答案是说-

“ lambda不会创建新的作用域,它们与封闭的块/环境共享相同的作用域”

在一个博客中-

“使用lambda表达式没有运行时的好处,所以我会谨慎使用它,因为我不介意写一些额外的代码行。”

从另一个博客-

“通过在方法中传递行为,又一个有益的lambda表达式顺序和并行执行支持”

所以对我来说,还有很多困惑。请帮助我清除此问题,以便在深入研究这些内容之前避免记住错误的方法。

我已经运行了以下代码,我可以说以下代码中的lambda表达式只是对匿名内部类及其在主线程上运行的替代。

List<Integer> list = new ArrayList<>();
list.add(12);
list.forEach(V -> {
    System.out.println(V);
});
Run Code Online (Sandbox Code Playgroud)

我们是在减少时间复杂度还是空间复杂度?

Hol*_*ger 6

lambda不会创建新的作用域,它们与封闭的块/环境共享相同的作用域 ”是几乎正确的声明(它们确实创建了一个新作用域,但不是内部类的方式),但是没有任何内容与运行时性能有关。这与代码的正确性有关。

在匿名内部类中,可以通过词法范围,在周围范围中找到匹配项或通过继承在匿名内部类的类层次结构中找到匹配项来解析标识符。在这种情况下,解析标识符的规则很复杂,很容易混淆。

此外,匿名类的主体创建了一个新的作用域,该作用域允许创建与周围环境的局部变量同名的变量,从而遮盖了这些变量。

相比之下,lambda表达式就像范围内都写在其他表达式。他们不继承从功能界面,他们将被转换到任何成员,它们不能创建新的变量阴影现有的局部变量,甚至thissuper具有相同在周围环境中的含义:

JLS§15.27.2。λ体

与出现在匿名类声明中的代码不同,lambda正文中出现的名称和thisand super关键字的含义以及引用声明的可访问性与周围上下文相同(除了lambda参数引入新名称)。

所以,当你有表达x.foo(y)() -> x.foo(y)同一区块内,这将是显而易见是否xy将是相同的x,并y为两个表达式,因此,这将是同样foo在每种情况下的方法,你不能说简单的匿名内部类,因为您必须首先分析整个内部类及其类型层次结构。

这使lambda表达式非常适合您要定义局部函数并将其作为参数传递给方法而又无需考虑实际interface使用情况的情况。除了定义功能签名之外,接口本身不会影响lambda表达式。

但这也意味着可能存在lambda表达式无法涵盖的匿名类的用例。但是lambda表达式的目的并不是要通用替代匿名内部类。


当谈到性能或易于并行处理时,shmosel的回答已经表明了这一点。我们不能在不知道我们正在查看哪个操作/问题以及实际上正在比较哪个解决方案的情况下做出此类一般性声明。


shm*_*sel 5

Lambda不会创建新的作用域,它们与封闭的块/环境共享相同的作用域

我不确定这句话的意思。

使用lambda表达式没有运行时优势

相对于什么?Lambda的性能可能优于匿名类,但都不比简单的控制流语句更好。

通过在方法中传递行为,又一个受益的lambda表达式顺序和并行执行支持

流和lambda支持声明式编程,这使并行化更易于访问。因此,使用lambda可以间接提高性能。