Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
I am reading couple of blogs and answers as well on lambda expression provided in Java 8.
I am not able to figure out, is there any run-time benefit of unit lambda expression or not?
I have copied following text from different sources which are too much confusing to me.
One answer is saying -
"lambdas do NOT create a new scope, they share the same scope as the
enclosing block/environment"
In the one blog -
"There are no runtime benefits of using lambda expressions, so I will
use it cautiously because I don’t mind writing few extra lines of
code."
From one other blog -
"one more benefit lambda expressions Sequential and Parallel Execution
Support by passing behavior in methods"
So there is lots off confusion for me.
Please help me to clear this so I can avoid keeping wrong approach in mind before digging more in to this stuff.
I have run following code and I can say the lambda expression in the following code is just replacement for the anonymous inner class and its running on main thread.
List<Integer> list = new ArrayList<>();
list.add(12);
list.forEach(V -> {
System.out.println(V);
});
Are we reducing any time complexity or space complexity?
“lambdas do NOT create a new scope, they share the same scope as the enclosing block/ environment” is an almost correct statement (they do create a new scope, but not the way inner classes do), but doesn’t have anything to do with runtime performance. This has to do with correctness of the code.
Within an anonymous inner class, identifiers may get resolved through the lexical scope, finding a match in the surrounding scope, or by inheritance, finding a match in the class hierarchy of the anonymous inner class. The rules for resolving identifiers in this scenario are complex and easy to confuse.
Further, the body of an anonymous class creates a new scope that allows to create variables having the same name as local variables of the surrounding context, shadowing these variables.
In contrast, a lambda expression works like other expressions within the context they are written in. They do not inherit any members from the functional interface they will get converted to, they can not create new variables shadowing existing local variables and even this
and super
have the same meaning as within the surrounding context:
JLS§15.27.2. Lambda Body
Unlike code appearing in anonymous class declarations, the meaning of names and the this
and super
keywords appearing in a lambda body, along with the accessibility of referenced declarations, are the same as in the surrounding context (except that lambda parameters introduce new names).
So when you have the expressions x.foo(y)
and () -> x.foo(y)
within the same block, it will be obvious whether x
and y
will be the same x
and y
for both expressions and hence, it will be the same foo
method in each case, which you can not say that simple for anonymous inner classes, as you have to analyze the entire inner class and its type hierarchy first.
This makes lambda expressions ideal for scenarios where you want to define a local function and, e.g. pass it to a method as a parameter, without even thinking about the actual interface
being used. The interface itself does not influence the lambda expression beyond defining the functional signature.
But this also implies that there might be use cases of anonymous classes that can’t be covered by lambda expressions. But the purpose of lambda expressions isn’t to be a general replacement for anonymous inner classes.
When it comes to performance or easy of parallel processing, shmosel’s answer says it already. We can’t make such general statements without knowing which operation/problem we are looking at and which solutions we are actually comparing.
lambdas do NOT create a new scope, they share the same scope as the enclosing block/environment
I'm not sure what your point is with this quote.
There are no runtime benefits of using lambda expressions
Relative to what? Lambdas may perform better than anonymous classes, but neither will outperform simple control flow statements.
one more benefit lambda expressions Sequential and Parallel Execution Support by passing behavior in methods
Streams and lambdas enable declarative programming, which makes parallelization more accessible. So using lambdas may indirectly improve performance.
anonymous inner class is compiled into extra .class file, but lambda is translated dynamically. Here is a detailed post: How will Java lambda functions be compiled?