Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where are Java 8 lambda expressions evaluated?

Tags:

Are the lambda expressions evaluated at the place where we write them or in any other class of Java?

For example :

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

Will the above lambda expression passed to the filter method be executed immediately in a given class where the code is written OR in another class and will it take some more time (in terms of nano seconds) than if the code was written in conventional coding style prior to Java 8?

like image 691
Oomph Fortuity Avatar asked Nov 24 '17 07:11

Oomph Fortuity


People also ask

Is lambda expressions introduced in Java 8?

Introduction. Lambda expressions are a new and important feature included in Java SE 8. They provide a clear and concise way to represent one method interface using an expression. Lambda expressions also improve the Collection libraries making it easier to iterate through, filter, and extract data from a Collection .

How do you evaluate a lambda expression?

Evaluating a Lambda Expression Evaluation is done by repeatedly finding a reducible expression (called a redex) and reducing it by a function evaluation until there are no more redexes. Example 1: The lambda expression (λx. x)y in its entirety is a redex that reduces to y.

What is the lambda expression in Java 8?

Lambda Expressions were added in Java 8. A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.


2 Answers

When you compile your sources, the compiler will insert an invokedynamic byte code instruction for the lambda expression that you use. The actual implementation (which in your case is a Predicate) will be created at runtime via ASM. It will not even be present on hard disk when you run it - meaning the class is generated in memory, there will be no .class file for Predicate. That's a big difference between an anonymous class for example - that will generate a class file when you compile it.

You can see the generated file for the Predicate if you run your example with :

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

Otherwise Eran's answer is correct, Streams are driven by the terminal operation, if such is not present nothing gets executed. You should absolutely read the excellent Holger's answer about even more interesting differences.

like image 71
Eugene Avatar answered Sep 26 '22 01:09

Eugene


The body of the lambda expression passed to the filter method in your example won't be executed at all, since filter is an intermediate operation, which only gets executed for Streams that end in a terminal operation, such as collect, forEach, etc...

If you add a terminal operation, such as collecting the elements of the Stream to a List:

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

the body of the lambda expression will be executed for each element of your Stream, in order for the terminal operation to be able to produce its output.

Note that this behavior would not change if you passed an anonymous class instance or some other implementation of the Predicate interface to your filter method instead of the lambda expression.

like image 41
Eran Avatar answered Sep 26 '22 01:09

Eran