What are the advantages of using lambda expression

2019-02-08 07:53发布

问题:

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 ?

回答1:

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);
}


回答2:

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.



回答3:

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)



回答4:

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.


回答5:

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.