Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.

Java 8 Revealed: Lambdas, Default Methods and Bulk Data Operations

What if you no longer had to redeploy your Java code to see changes? The choice is yours. In just a few clicks you can Say Goodbye to Java Redeploys forever.

Part 1: Lambdas in Java 8

In this part we are going to take a look at the syntax of the lambda expressions. We’ll point the transition path from the traditional old-school Java syntax to the brand new lambda syntax.

We will also take a look under the covers – to see how lambdas are represented by the runtime and what bytecode instructions are involved.

Getting started

If you are familiar with other languages that include lambda expressions, such as Groovy or Ruby, you might be surprised at first that it is not as simple in Java. In Java, lambda expression is SAM type, which is an interface with a single abstract method (yes, interfaces can include non-abstract methods now (default/defender methods which we’ll go over later in the text).

For instance, the well known Runnable interface is perfectly suitable for serving as a SAM type:

Runnable r = () -> System.out.println("hello lambda!");

Or the same could be applied to the Comparator interface:

 Comparator cmp = (x, y) -> (x < y) ? -1 : ((x > y) ? 1 : 0);

The same can be written as follows:

Comparator cmp = (x, y) -> {
    return (x < y) ? -1 : ((x > y) ? 1 : 0);
};

So it seems like the one-liner lambda expressions have implicit return for the statement.

Let me remind you how the same Comparator code is implemented in the pre-Java 8 syntax:

Comparator cmp = new Comparator() {
  @Override
  public int compare(Integer x, Integer y) {
    return (x < y) ? -1 : ((x > y) ? 1 : 0);
  }
};

As you can see, there’s a good portion of the code that is identical in both examples, and that is the real code–the functional part of the comparator:

(x < y) ? -1 : ((x > y) ? 1 : 0)

Basically, what we care about when transforming the old-style Java syntax to the lambda syntax is the set of the parameter of the interface method, and the functional part itself.

Let’s take a look at another example. What if I want to write a method that can accept a lambda expression as a parameter? Well, you have to declare the parameter as a functional interface, and then you can pass the lambda in:

interface Action {
  void run(String param);
}

public void execute(Action action){
  action.run("Hello!");
}

If we want to call the execute(..) method, we would normally pass it an anonymous implementation of the Action interface:

execute(new Action {
  public void run(String param){
    System.out.println(param);
  }
});

But as we now have a functional interfaces type as a parameter, we can invoke the execute(..) method as follows:

execute((String param) -> System.out.println(param));

Not that we can actually omit the lambda parameter type declaration:

execute(param -> System.out.println(param));

Generally, the rule is as follows: You either declare the types of all the parameters for the lambda, or omit all of them

Effectively, the same expression can be replaced with a method reference since it is just a single method call with the same parameter as is:

execute(System.out::println);

However, if there’s any transformations going on with the argument, we can’t use method references and have to type the full lambda expression out:

execute(s -> System.out.println("*" + s + "*"));

The syntax is rather nice and we now have quite an elegant solution for lambdas in the Java language despite the fact Java doesn’t have functional types per se.


Download the PDF