Skip to main content

8.1 Lambda Expressions

← Back to Chapter 8: Java 8 Features

Lambda expressions, introduced in Java 8, bring functional programming capabilities to Java. They provide a clear and concise way to represent single-method interfaces (Functional Interfaces) using an expression.


What is a Lambda Expression?​

A lambda expression is an anonymous function — a function without a declared name, return type, or explicit access modifiers. It can be passed around as if it were an object and executed on demand.

(parameters) -> { expression or statements }
▲ ▲ ▲
│ │ │
Argument Lambda Body / Logic
List Operator

Suppose we have a simple interface:

@FunctionalInterface
interface Calculator {
int add(int a, int b);
}

Before Java 8, we could implement it using an anonymous class:

Calculator calculator = new Calculator() {
@Override
public int add(int a, int b) {
return a + b;
}
};

This is a lot of code for such a simple operation.

With Lambda:

Calculator calculator = (a, b) -> a + b;

That's the main purpose of Lambda:

Remove unnecessary boilerplate code and make it easy to pass behavior as a value.

Without Lambda:

Object → Class → Method → Behavior


With Lambda:

Object → Behavior

That's why Lambda is so useful with:

Streams
Collections
Functional interfaces
CompletableFuture
Event handling
Spring code

Different Lambda forms​

No/Zero Parameter​

// 1. Zero arguments
() -> System.out.println("Hello, Java 8!");

Single Parameter​

// 2. Single parameter (type inference allows omitting parentheses and type)
name -> System.out.println("Hello, " + name);

Parentheses are optional for one parameter.

(name) -> System.out.println(name);

Multiple Parameters​

// 3. Multiple parameters with explicit types
(int a, int b) -> a + b;

Multiple Parameters with Inferred Types​

// 4. Multiple parameters with inferred types (most common)
(a, b) -> a + b;

Multi-line Body​

// 5. Multi-line body (requires curly braces and explicit return if returning a value)
(a, b) -> {
int sum = a + b;
System.out.println("Sum: " + sum);
return sum;
};

When using { }, if the Lambda needs to return a value, you normally use return.


Lambda does NOT have a type by itself​

You cannot normally do:

var x = () -> System.out.println("Hello");

because a Lambda needs a target functional interface type.

For example:

Runnable r = () -> System.out.println("Hello");

Here Java knows:

Lambda
↓
Runnable
↓
run()

That's how Java understands what the Lambda represents.

Why Functional Interface is required​

A Lambda represents the implementation of one abstract method.

Lambda and Variable Scope​

Suppose:

int number = 10;

Runnable r = () -> {
System.out.println(number);
};

This is allowed.

But if you try:

int number = 10;

number = 20;

Runnable r = () -> {
System.out.println(number);
};

This is not allowed.

Why?

Because a local variable used inside a Lambda must be final or effectively final.

What does effectively final mean?​

It means: You don't have to explicitly write final, but you must not change the variable after assigning it.

Modern Java 8 Lambda:​

Runnable r2 = () -> System.out.println("Thread running via Lambda");
AspectAnonymous Inner ClassLambda Expression
BoilerplateHigh (class declaration, method signature)Minimal (parameters and arrow body)
Bytecode GenerationCreates separate .class file (Outer$1.class)Uses invokedynamic (no extra class file)
this KeywordRefers to the inner class instance itselfLexically scoped: refers to enclosing class
TargetCan implement interfaces or extend abstract/concrete classesCan only implement Functional Interfaces
PerformanceHigher memory footprint and classloader overheadLower memory footprint, faster startup

Version wise updates​

Java VersionLambda-related change
Java 8⭐ Lambda introduced
Java 9No major Lambda change
Java 10var introduced for local variables, not Lambda parameters
Java 11⭐ var allowed in Lambda parameters
Java 12–17No major Lambda change
Java 18–20No major Lambda change
Java 21No major Lambda change
Java 22–24No major Lambda change
Java 25No major Lambda change
Java 26No major Lambda change