Lambda is a language feature introduced since Java SE 8, it is a concise expression to represent a block of code that takes in parameters and returns a value. Lambda expressions are similar to methods but they do not need a name and can be implemented right in the body of a method.

Note

Lambda expression cannot contain variables, assignments or statements such as if or for.

Basic syntax

(parameter_list) -> { body }

parameter_list is a comma-separated list of parameters that the lambda expression can accept. The parameter list can be zero parameter or more parameters. In most cases you can omit the type of parameter in a lambda expression when the compiler can infer it from the context using type inference.

-> is an lambda operator divides the parameter list from the body of expression.

{ body } is the code block that gets executed when the lambda expression is invoked, it can contain one or more statements.

Example

(int a, int b) -> { return a + b; }

This example is a simple lambda expression that represents a function that adds two numbers.

Lambda with functional interfaces

Lambda expressions are often used with functional interfaces which are interfaces with a Single Abstract Method or SAM. You can think of a lambda expression as an implementation of that SAM.

Example 1 - Without lambda

The below code implements the functional interface using anonymous nested class.

@FunctionalInterface
interface Addable {
    void add(int a, int b);
}
public class Demo {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        Addable ad = new Addable() {
            public void add(int x, int y) {
                System.out.println(x + y);
            }
        };
        ad.add(a, b);
    }
}
 

Using lambda expression Now we rewrite the program using lambda expression.

public class Demo {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        // use lambda to implement the add method
        Addable ad = (x, y) -> System.out.println(x + y);
        ad.add(a, b);
    }
}
30

To improve clarity, you can add curly braces and parameter type.

public class Demo {
    public static void main(String[] args) {
        int a = 10;
        int b = 20;
        // add parameter type and enclose expression body with braces
        Addable ad = (int x, int y) -> {
	        System.out.println(x + y);
        };
        ad.add(a, b);
    }
}
30

Example 2 - Lambda with return

Lambda expression can have return values. Single line lambda statement without return keyword:

@FunctionalInterface
interface Addable {
    int add(int a, int b);
}
public static void main(String[] args) {
	int a = 10;
	int b = 20;
	Addable ad = (x, y) -> x+y;
	
	System.out.println(ad.add(10, 20));
}

Multiple line lambda statements with return keyword:

public static void main(String[] args) {
	int a = 10;
	int b = 20;
	Addable ad = (x, y) -> {
		return x+y;
	};
	
	System.out.println(ad.add(10, 20));
}

Example 2

Lambda also works with functional interfaces in the Java Standard Library such as Runnable, Predictate and Consumer.

The lambda can work with forEach method which is a part of Java Stream API and takes a functional interface called Consumer.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(n -> System.out.println(n));

Here the forEach is called on numbers list, it takes the lambda expression as its argument.

Lambda expression and its parameter The lambda expression is an implementation of Consumer interface, the (n -> System.out.println(n)) represents a anonymous Consumer<Integer> object, since parameter n is inferred as Integer.

Expression body The only abstract method of Consumer accpept is implemented by taking the parameter n and its body System.out.println(n).

Without using lambda expression, you typically use anonymous nested class:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
 
Consumer<Integer> printConsumer = new Consumer<Integer>() {
	@Override
	public void accept(Integer n) {
		System.out.println(n);
	}
};
 
// use forEach with the created Consumer
numbers.forEach(printConsumer);

The forEach method takes each element (integer) from the list and assigns it to the variable n, and then it performs the action specified. (more on forEach method: Java collections framework/Iterable Interface/forEach)

Example 3

Here is an example of using lambda expression with Predicate functional interface to filter a list of integers.

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream()
    .filter((Integer n) -> n % 2 == 0)
    .collect(Collectors.toList());

In this example, the lambda expression (Integer n) -> n % 2 == 0 is used as a predicate to filter out even numbers from the list.

Lambda with Java stream API


Back to parent page: Java Standard Edition (Java SE) and Java Programming

Web_and_App_DevelopmentProgramming_LanguagesJavaLambda_Expression Functional_InterfaceAnonymous_Nested_Class