One of the main words to retain about lambda expressions is anonymous. A lambda expression is, basically, an anonymous function. Lambdas Expressions are a normal feature in functional languages but just few time ago arrived into the Java world. Better late than never though!

Why is it important?

If you are like me, you will be pleased with writing as less code as possible without losing expressiveness. And that’s one of the great advantages of lambdas.

It allows you to write shorter, more objective, more concise and more expressive code. And all this using functional programming style, which is cool!

If you are familiar with Anynomous classes, lambdas will feel like a breeze to you. If you are not, no worries.

How to interpret them

We tend to feel overwhelmed when looking at code with some uncommon syntax, but this is very simple, really.

Let’s first look into a simple method in Java:

String hello(String name) {
    return "Hello " + name;
}

From this, we read that we have this function named hello that receives a String argument (tagged name) and it returns a String by prepending “Hello “ to the argument.

Notice the amount of code to do this.

Lambda expressions look like this:

argument -> function code

Quite simple, right?

So the function above, as a lambda expression, looks like this:

name -> "Hello " + name

Pretty, right?

How to apply them (not yet)

From the example above, you might be wondering how you can actually use that lambda in order to produce something.

That is one interesting point to discuss and uncover.

Before that (believe me, it will be helpful), let me show you how lambda expressions are used a functional language like Haskell.

In Haskell, the function equivalent to the method above looks like this:

hello :: String -> String
hello = ("Hello " ++)
--or
hello x = "Hello " ++ x 

And the equivalent lambda expression to this is:

\x -> "Hello " ++ x

The point here is that I can apply both in the same way.

ghci> hello "world"
"Hello world"

ghci> (\x -> "Hello " ++ x) "world"
"Hello world"

In Java, this is not the case.

How to use lambdas in Java

I brought up the Anonymous Classes above because Lambda expressions have very much the same purpose.

Oracle’s introductory paragraph about lambda expressions states the following:

One issue with anonymous classes is that if the implementation of your anonymous class is very simple, such as an interface that contains only one method, then the syntax of anonymous classes may seem unwieldy and unclear. In these cases, you're usually trying to pass functionality as an argument to another method, such as what action should be taken when someone clicks a button. Lambda expressions enable you to do this, to treat functionality as method argument, or code as data.

The key idea is trying to pass functionality as an argument.

Before, this was eased through the use of Anonymous classes.

A Practical Example

Consider the following example where:

  • you are accessing a web service
  • the methods available to fetch data from it might throw an exception
  • you want to map it to Optional instead of having to deal with [nulls and exceptions](http://nunoalexandre.github.io/2016/08/31/why-optional-is-better-than-null) around your system.

1. I start by creating this functional interface:

@FunctionalInterface
public interface FallibleAction<T> {
    T result() throws Exception;
}

In other words, a FallibleAction is an Object with a single method, result, that returns something of type T that might throw an Exception.

2. Then I create the mapping / adapter abstraction from the outside world os nulls and exceptions into the inside world of Optional:

public class Try {
    public static <T> Optional<T> toGet(FallibleAction<T> action) {
        try {
            return Optional.ofNullable(action.result());
        } catch (Exception e) {
            return Optional.empty();
        }
    }
}

3. Now it’s time to wrap the web service

public final class AdaptedWebService {
    private final SomeWebService ws; 

    public AdaptedWebService(final SomeWebService ws) {
        this.ws = ws;
    }

    /*** the juicy part ***/

    public final Optional<Book> book(final Long bookId) {
        ...
    }

    public final Optional<Album> album(final Long albumId) {
        ...
    }

    public final Optional<Movie> movie(final Long movieId) {
        ...
    }


3.1. With Anonymous Classes I would implement those methods like:

public final Optional<Book> book(final Long bookId) {
    return Try.toGet(new FallibleAction<Book>() {
             @Override
             public Book result() throws Exception {
                 return ws.book(bookId);
             }
        });
}

public final Optional<Album> album(final Long albumId) {
    return Try.toGet(new FallibleAction<Album>() {
             @Override
             public Album result() throws Exception {
                 return ws.album(albumId);
             }
        });
}

public final Optional<Movie> movie(final Long movieId) {
    return Try.toGet(new FallibleAction<Movie>() {
             @Override
             public Movie result() throws Exception {
                 return ws.album(movieId);
             }
        });
}

This is already much better than to have to create specific classes implementing FallibleAction for each of this actions (and there are only three here, now imagine how 10 would look).

And finally…!

Still, this is a lot of code and a lot of repetition.

So this is how this methods look by using lambda expressions instead of Anonymous classes to pass functionality as an argument:

public final Optional<Book> book(final Long bookId) {
    return Try.toGet(() -> ws.book(bookId));
}

public final Optional<Album> album(final Long albumId) {
    return Try.toGet(() -> ws.album(albumId));
}

public final Optional<Movie> movie(final Long movieId) {
    return Try.toGet(() -> ws.movie(movieId));
}

Doesn’t this look beautiful? We (not) just reduced the amount of code by about 13 lines and made it highly expressive, concise and objective.

Note: A Java lambda in the form () -> … means that it has no arguments. An example with argument is applied like this, where it receives an Integer and returns that plus one:

list.stream().map(x -> x+1).collect(Collectors.toList());

Conclusion

So lambda expressions in Java actually are an anonymous object with a single method, being represented by what that method does.

Love the lambda!