28
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 ?

Prasad Revanaki
  • 783
  • 4
  • 10
  • 23
  • 4
    Concise code, more readability, less ceremony to do simple things i.e. replacement of anonymous class (you still have to write an anonymous class, in case of lambda you don't have to write a class). Reuse of code, create lambda expressions and pass it around methods. Further more introduction of lambda enabled number of good things in API such as Stream which provides an abstraction over the iteration. – Bilbo Baggins Nov 03 '15 at 05:57
  • 1
    For the use of lambda and why it is introduced read this book : Java 8 Lambdas by Richard Warburton – Bilbo Baggins Nov 03 '15 at 06:03
  • 2
    In short: Less boilerplate code = more maintainability. – Mark Jeronimus Nov 03 '15 at 09:08

6 Answers6

21

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);
}
shazin
  • 21,379
  • 3
  • 54
  • 71
  • 1
    I remember [Venkat Subramaniam](https://www.linkedin.com/in/vsubramaniam) speaking about this in one of his conferences. In that video, he also told the above piece of functionality not only benefits java but also jvm typed languages such as Scala etc., Many Thanks for pointing out! – harshavmb Sep 11 '17 at 10:55
  • See article, Java 8 Lambdas - A Peek Under the Hood,https://www.infoq.com/articles/Java-8-Lambdas-A-Peek-Under-the-Hood – BJYC Mar 22 '18 at 22:15
  • 1
    AIC does generate more bytecode, I/O files, though not sure how significant by reducing the final jar with lambda. With invokedynamic, the translations of lambda expressions are actually delayed to RT, so lambda isnot necessarily beneficial in terms of performance/space. The main benefits of lambda are making code more "readable" (which is debatable), concise/compact. It enables functional programming, a big gain comparing with other competing functional languages, e.g Scala. Together w/ scream interface, it enables the support of parallel processing, a big deal on parallel multi-processors. – BJYC Mar 22 '18 at 22:57
8

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.

ttarczynski
  • 949
  • 1
  • 10
  • 19
7

Advantages of lambda expressions

  1. It reduces the lines of code.
  2. It supports sequential and parallel execution by passing behavior in methods with collection stream API.
  3. Using Stream API and lambda expression we can achieve higher efficiency (parallel execution) in the case of bulk operations on collections.
piet.t
  • 11,718
  • 21
  • 43
  • 52
Anand Sinha
  • 322
  • 3
  • 7
  • 1
    Well... 2nd and 3rd are still can be done without lambdas and by only using anonymous classes.... So I would disagree with 2nd and 3rd reasons. – Pasha Dec 17 '19 at 22:38
7

One more - unlike anonymous classes, lambdas do NOT create a new scope, they share the same scope as the enclosing block/environment.

So:

  1. 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)

  2. There are no shadowing issues (as you cannot define local variables with the same names as variables in the enclosing scope)

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Ashutosh A
  • 975
  • 7
  • 10
3

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());
KrishPrabakar
  • 2,824
  • 2
  • 31
  • 44
1

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.