Engineering Full Stack Apps with Java and JavaScript
In functional programming, we think in terms of functions. While Object Oriented programming abstract over data, functional programming abstract over behavior. Instead of data, stateless functions are be passed across the code.
Lambda expressions are Java's way of doing functional programming. Lambda expressions in computer science are anonymous functions: a function (or a subroutine) defined, and possibly called, without being bound to an identifier.
Lambda expressions in Java provide an easy and precise way to implement an interface with only one single abstract method without referring to the method name at all. Since the interface has only one single method (function), passing across that interface implementation gives the impression of passing across that function.
Quick Example:
Runnable implementation without lambda expression:
Runnable r = new Runnable() {
@Override
public void run()
{
System.out.println("run");
}
}
Runnable implementation with lambda expression:
Runnable r = () -> System.out.println("run");
Most of the things are inferred by Java here.
Important points about lambda expressions can be summarized as:
The target type of a lambda expression is the type of the context in which lambda expression is defined. E.g. In 'Runnable r = () -> System.out.println("run");' the right hand side of the equals operator represents a lambda expression and its type is Runnable.
If a lambda expression is passed as a method parameter, the type will be of that method parameter.
Lambda expressions are Java's way of doing functional programming.
Lambda expressions can only appear in places where they will be assigned to a variable whose type is a functional interface: E.g. In 'Runnable r = () -> System.out.println("run");' Runnable is a functional interface.
Lambda expressions in Java are actually implementations of a functional interface.
Functional interfaces are interfaces with only a single abstract method, that is used as the type of a lambda expression.
Important points about functional interfaces can be summarized as follows:
Optionally, you can use the informative annotation type @FunctionalInterface annotation over an interface to indicate that it is a functional interface.
Instances of functional interfaces can be created with lambda expressions, method references, or constructor references.
Default methods or any abstract method overriding one of the public methods of java.lang.Object, are not counted towards the single abstract method requirement for becoming a functional interface.
Already existing interfaces Runnable, Callable,comparator,TimeTask etc. are functional interfaces.
Java 8 introduces few general purpose functional interfaces based on the input and output to the single abstract method. Most common ones are Predicate<T>, Consumer<T>, Function<T,R>, Supplier<T>, UnaryOperator<T> and BinaryOperator<T,T>. We will see some examples for these soon.