Java 8 lambda 表达式在哪里计算?

2022-09-02 03:07:06

lambda 表达式是在我们编写它们的地方还是在任何其他 Java 类中计算的?

例如:

Stream<Student> absent =  students.values().stream().filter(s -> !s.present());

上述传递给 filter 方法的 lambda 表达式是否会在给定的类中立即执行,其中代码是在另一个类中编写的,并且与 Java 8 之前的常规编码样式编写代码相比,是否会花费更多的时间(以纳秒为单位)?


答案 1

编译源代码时,编译器将为您使用的 lambda 表达式插入字节码指令。实际的实现(在您的情况下是 a)将在运行时通过 创建。当您运行它时,它甚至不会出现在硬盘上 - 这意味着该类是在内存中生成的,不会有.例如,这是匿名类之间的一个很大的区别 - 它会在编译时生成一个文件。invokedynamicPredicateASM.classPredicateclass

如果您使用以下命令运行示例,则可以看到 生成的文件:Predicate

-Djdk.internal.lambda.dumpProxyClasses=/Your/Path/Here

否则,Eran的答案是正确的,s是由终端操作驱动的,如果不存在,则不会执行任何内容。你绝对应该阅读优秀的Holger的答案,关于更有趣的差异。Stream


答案 2

在您的示例中传递给过滤器方法的 lambda 表达式的主体根本不会执行,因为它是一个中间操作,它只对在终端操作中结束的 s 执行,例如 , , 等...filterStreamcollectforEach

如果添加终端操作,例如将 的元素收集到 :StreamList

List<Student> absent =  students.values().stream().filter(s -> !s.present()).collect(Collectors.toList());

lambda 表达式的主体将针对 您的 每个元素执行,以便终端操作能够生成其输出。Stream

请注意,如果您将匿名类实例或接口的某个其他实现传递给您的方法而不是 lambda 表达式,则此行为不会更改。Predicatefilter


推荐