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?
The expressions are lazy evaluated, which means they'll only actually be evaluated when you actually try to 'terminate' the stream - i.e. use an operation that takes a stream but returns something else, like
collect
,min
,max
,reduce
, etc. Operations which take a stream as input and return a stream as output are usually lazy.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 aPredicate
) will be created at runtime viaASM
. 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 forPredicate
. That's a big difference between an anonymous class for example - that will generate aclass
file when you compile it.You can see the generated file for the
Predicate
if you run your example with :Otherwise Eran's answer is correct,
Stream
s 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.Lambda expressions are essentially objects with a single method, so they're evaluated whenever that method is called.
In your particular case they're never evaluated. A Stream does not evaluate the expressions until you call a terminating operation (
collect
,findAny
, etcetera)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 forStream
s that end in a terminal operation, such ascollect
,forEach
, etc...If you add a terminal operation, such as collecting the elements of the
Stream
to aList
: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 yourfilter
method instead of the lambda expression.