Home/Learn/Java A–Z/Lambda Expressions

Lambda Expressions

Intermediate
Streams & Functional Java

Write concise, inline function objects with lambda syntax — the foundation of functional-style Java introduced in Java 8.

Overview

A lambda expression is a short anonymous function that can be passed around as a value. It provides a cleaner syntax for implementing functional interfaces compared to anonymous inner classes. The syntax is (parameters) -> body. Lambdas can capture effectively final local variables from the enclosing scope, enabling powerful patterns like callbacks, event handlers, and strategy injection.

Lambda Syntax & Variations

Lambda syntax: (params) -> expression or (params) -> { statements; }

The parameter types can be omitted — the compiler infers them from the functional interface context. Parentheses can be dropped for a single parameter. The return keyword and braces are optional for a single expression.

LambdaSyntax.java
import java.util.*;
import java.util.function.*;

public class LambdaSyntax {
    public static void main(String[] args) {
        // Zero parameters
        Runnable r = () -> System.out.println("Running");
        r.run();

        // One parameter — parentheses optional
        Consumer<String> print = s -> System.out.println(s.toUpperCase());
        print.accept("hello");  // HELLO

        // Two parameters
        Comparator<Integer> cmp = (a, b) -> a - b;
        System.out.println(cmp.compare(3, 5)); // -2

        // Block body — multiple statements, explicit return
        Function<Integer, String> grade = score -> {
            if (score >= 90) return "A";
            if (score >= 80) return "B";
            return "C";
        };
        System.out.println(grade.apply(85)); // B

        // Lambdas as arguments
        List<String> names = new ArrayList<>(List.of("Charlie", "Alice", "Bob"));
        names.sort((a, b) -> a.compareTo(b));
        System.out.println(names); // [Alice, Bob, Charlie]

        names.forEach(name -> System.out.print(name + " "));
        System.out.println();
    }
}

Variable Capture & Effectively Final

Lambdas can capture local variables from the enclosing scope, but those variables must be final or effectively final (never reassigned). Instance fields and static fields can be read and written freely — only local variables are restricted.

Why? Each lambda invocation shares the same captured variable. If it could change between capture and use, behaviour would be unpredictable in concurrent contexts.

LambdaCapture.java
import java.util.List;
import java.util.function.Predicate;

public class LambdaCapture {
    private int instanceField = 10; // can be freely accessed/modified

    void demo() {
        int localVar = 5;      // effectively final — never reassigned
        // localVar = 6;       // uncommenting this breaks the lambda below

        Predicate<Integer> greaterThanLocal = n -> n > localVar;    // OK
        Predicate<Integer> greaterThanField = n -> n > instanceField; // OK

        System.out.println(greaterThanLocal.test(8));  // true
        instanceField = 20; // modifying instance field is fine
        System.out.println(greaterThanField.test(15)); // false (20 > 15 = false)

        // Capturing loop variable — must copy to effectively final
        List<Runnable> tasks = new java.util.ArrayList<>();
        for (int i = 0; i < 3; i++) {
            final int copy = i; // effectively final copy
            tasks.add(() -> System.out.print(copy + " "));
        }
        tasks.forEach(Runnable::run); // 0 1 2
        System.out.println();
    }

    public static void main(String[] args) { new LambdaCapture().demo(); }
}

Lambda vs Anonymous Class

Lambdas replace single-method anonymous inner classes. Key differences: • Lambda has no this — inside a lambda, this refers to the enclosing class • Anonymous class creates a new .class file; lambda is a invokedynamic call site — lighter at runtime • Lambda can only implement a functional interface (one abstract method) • Anonymous class can implement any interface or extend a class

LambdaVsAnon.java
import java.util.Comparator;

public class LambdaVsAnon {
    private String name = "Outer";

    void compare() {
        // Anonymous class — verbose, own 'this'
        Comparator<String> anonCmp = new Comparator<String>() {
            @Override
            public int compare(String a, String b) {
                System.out.println(this.getClass().getSimpleName()); // anonymous class name
                return a.length() - b.length();
            }
        };

        // Lambda — concise, this = enclosing LambdaVsAnon instance
        Comparator<String> lambdaCmp = (a, b) -> {
            System.out.println(this.name); // "Outer" — enclosing class this
            return a.length() - b.length();
        };

        System.out.println(anonCmp.compare("hi", "hello"));   // -3
        System.out.println(lambdaCmp.compare("hi", "hello")); // -3
    }

    public static void main(String[] args) { new LambdaVsAnon().compare(); }
}

Interactive Visualization

.source()
.filter()
.map()
.sorted()
.collect()
1
2
3
4
5
6
7
8
stream.filter(n → n%2==0).map(n → n*n).sorted().collect(toList())
Source: a stream of integers [1, 2, 3, 4, 5, 6, 7, 8].
1 / 5

Key Points to Remember

  • Lambda syntax: (params) -> expr or (params) -> { body; return val; }
  • Parameter types and parentheses (single param) can be omitted — compiler infers them
  • Captured local variables must be final or effectively final
  • Inside a lambda, this refers to the enclosing class, not the lambda itself
  • Lambdas are compiled to invokedynamic — lighter than anonymous inner classes
  • A lambda can only implement a functional interface (exactly one abstract method)

Practice Lambda Expressions in the Playground

Run and modify code directly in your browser - no setup needed.

Interview Questions

Sign in to ask Aria
1

What is a lambda expression in Java? When was it introduced?

EasyTCS
2

Why must captured local variables be effectively final in lambdas?

MediumGoogle
3

What is the difference between a lambda and an anonymous inner class?

MediumAmazon
4

Can a lambda expression throw a checked exception?

MediumOracle
5

What does "this" refer to inside a lambda expression?

MediumMicrosoft

Ask Aria about Lambda Expressions

Your personal AI tutor — ask anything about this concept