Reputation: 783
Interface AccountService{
public void createAccount();
}
AccountService accountServiceAnonymous = new AccountService(){
public void createAccount(){
Account account = new Account();
save(account);
}
};
AccountService accountServiceLambda = () -> {
Account account = new Account();
save(account);
}
Apart from reduced number of lines of code, are there any other advantages of using lambda expressions in java 8 ?
Upvotes: 28
Views: 26615
Reputation: 2842
One (more) advantage Lambdas offer is Laziness (thereby improving performance):
Before Lambdas, a log statement looks like this:
logger.trace("Costly Metrics: {}", expensiveCompuatation());
The expensiveCompuatation()
gets invoked regardless of whether trace is enabled or not, wasting CPU cycles.
To avoid such costly invocations, we used to write:
if (logger.isTraceEnabled()) {
logger.trace("Costly Metrics: {}", expensiveCompuatation());
}
Although it meets the needs, now the code looks ugly with more if
statements causing code bloat.
After Lambdas, now the log statement looks crisp and neat (without surrounding if statements) and allows delaying the expensive operation:
logger.trace("Costly Metrics: {}", () -> expensiveCompuatation());
logger.trace("Costly Metrics: {}, {}", () -> expensiveOp1(), () -> expensiveOp2());
logger.trace("Costly Metrics: {}, {}", this::expensiveOp1(), this::expensiveOp2());
Upvotes: 3
Reputation: 322
Advantages of lambda expressions
Upvotes: 7
Reputation: 1025
One more - unlike anonymous classes, lambdas do NOT create a new scope, they share the same scope as the enclosing block/environment.
So:
It's easier to access the enclosing object - plain this
reference refers to the instance of the enclosing class (and you don't need to say EnclosingClass.this
)
There are no shadowing issues (as you cannot define local variables with the same names as variables in the enclosing scope)
Upvotes: 7
Reputation: 317
In addition to what has been said here, and to strictly answer the question raised, it is important to see lambdas as a "block of code" that, among other things, can be passed as parameter. That provides a huge advantage due to you can remove duplicated code.
How is that ? In the example above presented by @Kitke, the pushToFront(...) method, if the requirement exists, might be refactored a bit as a template and be used to filter registeredWindows by any condition. The lambda expression window -> window.getWindowId() == contactInfo.getId(), can be passed as parameter in that case. Without this powerful feature, you have to write the while loop every time you need to filter the registeredWindows collection by a different condition. Huge gain, re-think your code with this in mind.
Extracted from: http://www.copypasteisforword.com/notes/lambda-expressions-in-java. There you can find another example of lambda usage to remove duplicated code.
Upvotes: 1
Reputation: 1014
Another advantage of lambdas (and method references) is visible when you combine them with Stream API and other features added in Java 8, e.g. Optional.
Consider this code:
private void pushToFront(AbstractInfo contactInfo) {
registeredWindows.stream()
.filter(window -> window.getWindowId() == contactInfo.getId())
.findAny()
.ifPresent(Window::pushToFront);
}
The method filters the list of registered windows matching windowId with contact's id returning an Optional. If the list contains window with matching id, then the value in Optional is present and pushToFront method is then on it. Compare this to the same functionality but written in Java 7:
private void pushToFront(AbstractInfo contactInfo) {
for (Window window : registeredWindows) {
if (window.getWindowId() == contactInfo.getId() {
window.pushToFront();
}
}
}
The code with lambda expression, stream and method reference, at least to me, is more concise and readable (when you get use to using streams). The example above is quite simple - but consider one, which in Java 7 would require nested loops, multiple conditional statements etc. Not easy to read even harder not to loose track of what's going on.
Lambdas then allow one to fully utilize other neat features of the Java 8 which among others result in neat, clean, efficient and easy to understand code.
Bottom line is, you should consider lambda expressions as part of a larger whole which are great for themselves but even better when combined with other 'building blocks' of Java 8.
Upvotes: 8
Reputation: 21883
Adding to what @Bilbo has mentioned in comments. In Java 1.7 there was a new JVM Opcode was released named invokedynamic
and Java 8 Lambda uses this. So the following code will result in an Anonymous class being created when you compile the code. Possible <ClassName>$1.class
so if you have 10 anonymous classes that is 10 more classes in the final jar.
AccountService accountServiceAnonymous = new AccountService(){
public void createAccount(){
Account account = new Account();
save(account);
}
};
But Java 8 lambda uses invokedynamic
to call lambdas thus if you have 10 lambdas it will not result in any anonymous classes thus reducing the final jar size.
AccountService accountServiceLambda = () -> {
Account account = new Account();
save(account);
}
Upvotes: 21