Prior to Java 1.8, writing Java code in a functional way was very heavyweight, requiring an interface and an anonymous class:
The OpenJDK Lambda Project [1] defines some of the imperfections of anonymous inner classes:
- Bulky syntax
- Confusion surrounding the meaning of names and this
- Inflexible class-loading and instance-creation semantics
- Inability to capture non-final local variables
- 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]: