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

Java lambda表达式每次执行时是否在堆上创建一个对象?

慎志国
2023-03-14
问题内容

当我使用Java 8的新语法糖遍历集合时,例如

myStream.forEach(item -> {
  // do something useful
});

这不等同于下面的“旧语法”代码段吗?

myStream.forEach(new Consumer<Item>() {
  @Override
  public void accept(Item item) {
    // do something useful
  }
});

这是否意味着Consumer每次迭代集合时都会在堆上创建一个新的匿名对象?这需要多少堆空间?它对性能有什么影响?这是否意味着在遍历大型多级数据结构时,我宁愿使用旧样式的循环?


问题答案:

它是等效的但不相同。简而言之,如果lambda表达式未捕获值,则它将是单例,可在每次调用时重复使用。

行为没有完全指定。JVM被赋予了很大的自由来实现它。当前,Oracle的JVM为每个lambda表达式创建(至少)一个实例(即不在不同的相同表达式之间共享实例),但为所有不捕获值的表达式创建单例。

你可以阅读此答案以获取更多详细信息。在那里,我不仅给出了更详细的描述,还提供了测试代码以观察当前行为。



 类似资料:
  • 这难道不等同于下面的“旧语法”片段吗? 这是否意味着每次迭代集合时都会在堆上创建一个新的匿名对象?这需要多少堆空间?它对性能有什么影响?这是否意味着我应该在迭代大型多级数据结构时使用旧的循环样式?

  • 我有下面的类和对象的ArrayList: 我想要的是从我的列表中得到一个字符串和整数地图,其中包含门票中的目的地和我列表中每个目的地的出现次数。我想它会这样开始,但是我不知道如何继续:

  • 我使用Eclipse数据库开发视角手动创建了一个模式和几个表。但是每当我试图从代码访问表时,我都会得到“架构不存在”错误。但是,如果我在使用这些表之前在程序中创建这些表,一切都会顺利。每次连接到数据库时都必须创建表吗?因为,我正在测试我的代码,我必须多次重启项目。

  • 问题内容: 所以,我不确定那是什么。如果在 ModuleA中 ,我有: 在 ModuleB中 ,我有: 在主程序中,我有: 因此,当我运行主程序时,我想我将创建两个猫鼬“实例”;一个连接到pathA,一个连接到pathB,对吗? 另外,在模块B中,在我连接到pathB之前,它是连接到pathA还是什么都没有? 谢谢。 问题答案: 我刚刚对最新的节点V0.4.6做了一些测试。我确认了以下内容: 从“

  • 问题内容: 我想从表中的数据创建json。表看起来像这样: 我正在使用FOR JSON PATH,这很不错: 但此查询的返回值是一行中的三个串联的json: 我需要每一行都是一个单独的json,像这样: 我正在尝试使用拆分函数(CROSS APPLY),该函数需要使用分隔符作为参数,但这不是一个可靠的解决方案,因为json可以进一步扩展或分支,并且可以不分离整个json,而是分离json内部的js

  • 我需要每隔周一和周三触发我的邮件。我在我的应用程序中使用JavaSpring。我尝试使用这个cron表达式和周三相同,但它在每月的1个周一和周三触发。我想要的是它应该在每月的第一、第三和第五周的周一和周三触发。 有人能帮我创建这个cron表达式吗?