Java 8 Feature – Lambda Expressions

Lambda expression is a significant new feature in Java 8 that enables developers to use functional programming features in Java code. The introduction of lambda expressions and related features in Java 8 has led to the addition of new syntax elements and constructs to the Java language. In this way, lambda expressions enhance the capabilities of Java 8 and reshape Java code.

What is a Lambda Expression?

A lambda expression is an unnamed method that is used to implement a functional interface method. A functional interface is an interface that defines an action using a single abstract method. To execute a lambda expression, you need to use a functional interface that defines the target type of the lambda expression. Lambda expressions are also called closures.

Lambda Expression Syntax

A lambda expression includes a parameter list, an arrow operator, and a lambda body.

(lambda expression parameter list) -> lambda body;

The lambda expression parameter list contains the set of parameters used by the lambda expression. You can use an empty parameter list if the lambda expression does not require any parameters. The arrow operator, also called the lambda operator, indicates that the parameters are moved into the lambda body and helps to segregate the parameter list from the code. The lambda body contains the code that defines the actions performed by the lambda expression.

The lambda body can contain either a single expression or a block of code. A single expression lambda body contains a simple Java expression. Such a lambda expression is called an expression lambda. When the lambda expression is executed, the expression in the lambda body is evaluated and the result is returned.

Example 1

() -> Math.random();

In this example, the lambda expression uses an empty parameter list. The lambda body contains an expression that returns a random number.

Example 2

(x,y) -> (x/y) == 5;

In this example, the lambda expression uses two parameters x and y. The expression in the lambda body evaluates the result of x/y and returns true if the result equals 5.

Functional Interfaces and Lambda Expressions

A functional interface consists of only one abstract method that clearly defines the function of the interface. In Java 8, lambda expression and a functional interface work together to perform the function defined by the interface. The functional interface specifies the target type of the lambda expression enabling you to implement the abstract method using a lambda expression.

Note: In earlier versions of Java, all interface methods were implicitly abstract. However, in Java 8, you can create default methods by specifying default behaviour for the methods in an interface. If a method in an interface does not specify a default implementation, Java 8 treats the method as an abstract method.

In Java 8 code, you can use a lambda expression only in a context that specifies its target type. Some of the possible target type contexts for using lambda expressions include:

  1. Variable initialization

  2. Return statements

  3. Assignment of a lambda expression to a functional interface reference

  4. Method arguments

Example

The following example illustrates the use of a simple lambda expression with two parameters.

LambdaExpDemo.java
interface TestNum {

    boolean factortest(int n1, int n2);

}

public class LambdaExpDemo {

    public static void main(String args[]) {

        TestNum isFactor;

        isFactor = (n1, n2) -> (n1 % n2) == 0;

        if (isFactor.factortest(20, 5)) {
            System.out.println("5 is a factor of 20");
        }

        if (!isFactor.factortest(20, 3)) {
            System.out.println("3 is not a factor of 20");
        }

    }
}

In this example, TestNum is a functional interface and factortest is the abstract method. isFactor is a reference to the TestNum functional interface. The lambda expression with two parameters n1 and n2 is assigned to isFactor. Java executes this assignment by creating an instance that implements the functional interface. The lambda expression specifies the behaviour of the abstract method. When the abstract method is called in the if statement, the lambda expression is executed and it returns a Boolean result.

Parameter Compatibility

For a lambda expression to work correctly, the number and type of parameters used in the lambda expression must match the parameters used in the abstract method. Also, the return type of the abstract method must match the return type of the lambda expression. For example, if there are two double and one string parameters in the abstract method, then the lambda expression must also specify three explicit or implicit parameters that are compatible with the abstract method parameters.

Block Lambda Expressions

In a lambda expression, the lambda body can contain a block of code. Such a lambda body is called a block body and the lambda expression that contains a block body is called a block lambda. A block body contains multiple statements enclosed within braces. A block lambda works the same way as an expression lambda. The only difference is that in a block lambda you need to use a return statement explicitly.

Example

The following program reverses a string using a block lambda expression and a functional interface.

LambdaExpDemo.java
interface ReverseString {

    String meth(String s);
}

public class LambdaExpDemo {

    public static void main(String args[]) {
        ReverseString rev = (str) -> {
            String revresult = "";
            int n;
            for (n = str.length() - 1; n >= 0; n--) {
                revresult += str.charAt(n);
            }
            return revresult;
        };
        System.out.println("The reverse of Java is " + rev.meth("Java"));
    }
}

Happy Learning 🙂