Master Core Java Programming From Scratch

Clear, interactive, and structured coding lessons designed for absolute beginners.

Lambda Expressions in Java

Learn how lambda expressions provide a concise way to represent behavior and work with functional interfaces, collections, streams, and modern Java APIs.

What is a Lambda Expression?

A lambda expression is a compact representation of behavior that can be passed as a value. Lambda expressions are closely associated with functional interfaces.

Java
(parameters) -> expression
Java
(parameters) -> {
    // statements
}

Basic Lambda Expression

Java
Runnable task = () -> {


   System.out.println("CIIT Institute background task is running successfully 🏠👍...!");

};

task.run();

The lambda () -> { ... } provides the implementation of the single abstract method of Runnable.

Lambda Parameters

Lambda expressions can accept zero, one, or multiple parameters.

Java
var square = (int number) ->
    number * number;

System.out.println(
    square.applyAsInt(5)
);

For compatible functional interfaces, parameter types can often be inferred.

Lambda and Functional Interfaces

A functional interface has exactly one abstract method. Lambda expressions can provide implementations for such interfaces.

Java
interface Calculator {

    int calculate(int a, int b);

}

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

System.out.println(
    addition.calculate(10, 20)
);

Expression Body vs Block Body

Java
Calculator add =
    (a, b) -> a + b;
Java
Calculator multiply =
    (a, b) -> {

        int result = a * b;

        return result;
    };

Built-in Functional Interfaces

Java provides many functional interfaces in java.util.function.

Interface Purpose
Predicate<T> Tests a condition and returns boolean.
Function<T,R> Converts an input into an output.
Consumer<T> Consumes an input without returning a result.
Supplier<T> Supplies a value without taking an input.
UnaryOperator<T> Transforms a value into the same type.
BinaryOperator<T> Combines two values of the same type.

Predicate

Predicate<T> represents a boolean-valued function.

Java
Predicate<Integer> isEven =
    number -> number % 2 == 0;

System.out.println(
    isEven.test(10)
);

Function

Function<T,R> accepts one value and produces another value.

Java
Function<String, Integer> length =
    text -> text.length();

System.out.println(
    length.apply("Java")
);

Consumer

Consumer<T> accepts a value and performs an operation without returning a result.

Java
Consumer<String> printer =
    text -> System.out.println(text);

printer.accept("Welcome to CIIT Institute: Learn, Code, and Succeed 👀👨‍🏫...!");

Supplier

Supplier<T> produces a value without taking an input.

Java
Supplier<Double> randomValue =
    () -> Math.random();

System.out.println(
    randomValue.get()
);

Method References

Method references provide an even shorter syntax when an existing method already matches the required functional interface.

Java
List<String> names =
    List.of(
        "Amit",
        "Neha",
        "Rahul"
    );

names.forEach(
    System.out::println
);

The expression System.out::println is a method reference.

Lambda with Collections

Java
List<String> names =
    new ArrayList<>();

names.add("Amit");
names.add("Neha");
names.add("Rahul");

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

Lambda for Sorting

Java
List<Integer> numbers =
    new ArrayList<>(
        List.of(50, 10, 40, 20)
    );

numbers.sort(
    (a, b) -> Integer.compare(a, b)
);

System.out.println(numbers);

For simple natural ordering, Java also provides Comparator.naturalOrder().

Lambda Expressions with Streams

Lambda expressions are widely used with the Stream API.

Java
List<Integer> numbers =
    List.of(
        10, 15, 20, 25, 30
    );

numbers.stream()
    .filter(number -> number > 20)
    .forEach(
        number ->
            System.out.println(number)
    );

Variable Capture

A lambda can access local variables from its enclosing scope when those variables are final or effectively final.

Java
int multiplier = 10;

Function<Integer, Integer> multiply =
    number -> number * multiplier;

System.out.println(
    multiply.apply(5)
);
Important: You cannot later reassign multiplier if it is being captured by the lambda.

this in Lambda Expressions

A lambda expression does not create a new this context. Inside a lambda, this refers to the enclosing object.

Java
class Printer {

    private String prefix = "Message: ";

    void print() {

        Consumer<String> action =
            text ->
                System.out.println(
                    prefix + text
                );

        action.accept("Hello");

    }

}

Lambda vs Anonymous Class

Java
Runnable task =
    new Runnable() {

        @Override
        public void run() {

            System.out.println(
                "Running"
            );

        }
    };
Java
Runnable task =
    () ->
        System.out.println(
            "Running"
        );

The lambda form is more concise when the target type is a functional interface.

When Should You Use Lambda Expressions?

  • Processing collections.
  • Filtering and transforming stream data.
  • Passing small pieces of behavior to APIs.
  • Implementing functional interfaces.
  • Creating concise callbacks and event-like operations.

Lambda Best Practices

  • Keep lambda expressions short and readable.
  • Use meaningful parameter names.
  • Prefer method references when they improve readability.
  • Avoid deeply nested lambda expressions.
  • Use a regular method when the lambda becomes too complex.

Interview Questions

A lambda expression is a concise representation of behavior that can be used where a compatible functional interface is expected.

A functional interface has exactly one abstract method and can be used as the target type of a lambda expression.

A lambda is a concise implementation of a functional interface, while an anonymous class creates an anonymous class instance and can define more structure and behavior.

Predicate tests a condition, Function transforms input into output, Consumer accepts input without returning a result, and Supplier produces a value without an input.

A method reference is a compact syntax such as System.out::println for referring to an existing compatible method.
Summary

Lambda expressions provide concise implementations of functional interfaces. They are heavily used with collections, Comparator, the Stream API, and the java.util.function package. Method references provide another concise way to reuse existing methods.