Chris Socha
by Chris Socha

Prior to Java 1.8, writing Java code in a functional way was very heavyweight, requiring an interface and an anonymous class:

methodWithCallback(new Runnable() {
    public void run() {
        // do a thing

The OpenJDK Lambda Project [1] defines some of the imperfections of anonymous inner classes:

  1. Bulky syntax
  2. Confusion surrounding the meaning of names and this
  3. Inflexible class-loading and instance-creation semantics
  4. Inability to capture non-final local variables
  5. Inability to abstract over control flow

Project Lambda addresses some of these issues.

Functional Interfaces

Functional Interfaces are any interface with a single method (e.g. Runnable). The compiler identifies these based on the structure of the interface, or the @FunctionalInterface annotation can be added to express the design intent of the interface to the compiler.

With existing libraries already extensively using functional interfaces, the Lambda Project continues to use this pattern which lets existing libraries use the new lambda expression. In additional to existing interfaces which fit the requirements of Functional Interfaces, Java 1.8 adds the following functional interfaces to java.util.function:

Predicate<T> a boolean-valued property of an object JavaDoc
Consumer<T> an action to be performed on an object JavaDoc
Function<T,R> a function transforming a T to a R JavaDoc
Supplier<T> provide an instance of a T (such as a factory) JavaDoc
UnaryOperator<T> a function from T to T JavaDoc
BinaryOperator<T> a function from (T, T) to T JavaDoc
BiFunction<T,U,R> a function from (T,U) to R JavaDoc

Lambda Expressions

Some examples of lambda functions [2]:

// with no parameter
() -> System.out.println("Hello, world.")

// with a single parameter (This example is an identity function).
a -> a

// with a single expression
(a, b) -> a + b

// with explicit type information
(long id, String name) -> "id: " + id + ", name:" + name

// with a code block
(a, b) -> { return a + b; }

More Reading: