Advanced Java August 19 ,2025

Java Lambda Expressions – 

Lambda Expressions were introduced in Java SE 8 to bring the principles of functional programming into the Java language. They provide a way to represent functions as objects, which makes code more concise and expressive compared to anonymous inner classes.

At their core, lambda expressions implement functional interfaces, i.e., interfaces with a single abstract method. This allows developers to write behavior directly where it is required, instead of creating a separate class.

Key Features of Lambda Expressions

  1. Functional Interface Implementation
    A lambda expression can be used only where a functional interface is expected. A functional interface is an interface with exactly one abstract method (for example, Runnable, Comparator, Callable).
  2. Code as Data
    Functions can be treated as data, which means they can be passed as arguments, stored in variables, and executed later.
  3. Reduction of Boilerplate Code
    Before Java 8, developers often used anonymous inner classes, which required multiple lines of code. Lambda expressions reduce this verbosity.
  4. Improved Readability and Maintainability
    With a cleaner syntax, code becomes easier to read and maintain.

Syntax of Lambda Expressions

(parameters) -> { body }

Components

  1. Parameters – Input to the lambda expression.
  2. Arrow Token (->) – Separates parameters from the body.
  3. Body – The actual logic to be executed.

Variations in Syntax

  • No parameter:

    () -> System.out.println("Hello");
    
  • Single parameter (parentheses optional if type is inferred):

    n -> n * n;
    
  • Multiple parameters:

    (a, b) -> a + b;
    
  • With code block:

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

Types of Lambda Expressions

Lambda expressions can be classified based on the number of parameters they accept. In Java, parameters can be zero, one, or multiple. The body of the lambda can either perform an action or return a value, depending on the functional interface used.

1. Lambda Expression with Zero Parameters

  • This type of lambda expression does not take any input argument.
  • It is useful when you want to execute a block of code that always performs the same action, regardless of input.
  • The corresponding functional interface should have a method with no parameters.
  • A common use case is when you want to create tasks for threads (Runnable) or when an event occurs but no input is required.

Example

@FunctionalInterface
interface ZeroParameter {
    void display();
}

public class Demo {
    public static void main(String[] args) {
        ZeroParameter obj = () -> System.out.println("Zero-parameter Lambda Expression");
        obj.display();
    }
}

Output

Zero-parameter Lambda Expression

2. Lambda Expression with a Single Parameter

  • This type of lambda takes exactly one argument.
  • Parentheses around the parameter are optional if the compiler can infer the type.
  • This form is useful for operations on collections, where each element is processed one at a time (for example, printing values, filtering, or transforming them).
  • It is often used with functional interfaces like Predicate, Consumer, and Function.

Example

import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        ArrayList numbers = new ArrayList<>();
        numbers.add(1); numbers.add(2); numbers.add(3); numbers.add(4);

        // Print all numbers
        numbers.forEach(n -> System.out.println("Number: " + n));

        // Print even numbers
        numbers.forEach(n -> {
            if (n % 2 == 0) {
                System.out.println("Even: " + n);
            }
        });
    }
}

Output

Number: 1
Number: 2
Number: 3
Number: 4
Even: 2
Even: 4

3. Lambda Expression with Multiple Parameters

  • This type of lambda expression accepts two or more input parameters.
  • All parameters must either have their types declared explicitly or be inferred by the compiler. You cannot mix explicit and inferred parameter types in the same lambda.
  • Multiple parameter lambdas are widely used in mathematical operations (addition, multiplication), comparisons (greater/lesser), or when working with Comparator for sorting objects.
  • The functional interface in this case must have a method that accepts multiple arguments. For example, BiFunction or Comparator.

Key Rules:

  1. If the body has a single statement, braces {} are optional.
  2. If the body has multiple statements, you must use braces {} and a return statement if a value is returned.
  3. You must declare parameter types consistently (either omit for all, or specify for all).

Example: Arithmetic Operations

@FunctionalInterface
interface Operation {
    int calculate(int a, int b);
}

public class Demo {
    public static void main(String[] args) {
        // Lambda to add two numbers
        Operation add = (a, b) -> a + b;

        // Lambda to multiply two numbers
        Operation multiply = (a, b) -> a * b;

        // Lambda with multiple statements
        Operation subtract = (a, b) -> {
            System.out.println("Subtracting " + b + " from " + a);
            return a - b;
        };

        System.out.println("Sum: " + add.calculate(5, 3));
        System.out.println("Product: " + multiply.calculate(5, 3));
        System.out.println("Difference: " + subtract.calculate(10, 4));
    }
}

Output

Sum: 8
Product: 15
Subtracting 4 from 10
Difference: 6

Example: Sorting with Comparator

import java.util.*;

public class Demo {
    public static void main(String[] args) {
        List names = Arrays.asList("John", "Alice", "Bob");

        // Sort using lambda with multiple parameters
        Collections.sort(names, (s1, s2) -> s1.compareToIgnoreCase(s2));

        System.out.println("Sorted names: " + names);
    }
}

Output

Sorted names: [Alice, Bob, John]

Summary of Types

Type of LambdaParametersExampleUse Case
Zero ParameterNone() -> System.out.println("Hi")Runnable, event handling
Single ParameterOnex -> x * xIterating lists, filtering
Multiple ParametersTwo or more(a, b) -> a + bComparisons, arithmetic, sorting

 

Commonly Used Built-in Functional Interfaces

Java provides several predefined functional interfaces in the java.util.function package.

  1. Predicate
    Represents a condition that takes one argument and returns true or false.

    Predicate isEven = n -> n % 2 == 0;
    System.out.println(isEven.test(10)); // true
    
  2. Function
    Represents a function that takes an argument of type T and returns a result of type R.

    Function convert = n -> "Number: " + n;
    System.out.println(convert.apply(5)); // Number: 5
    
  3. Consumer
    Represents an operation that accepts a single argument and returns no result.

    Consumer print = s -> System.out.println(s);
    print.accept("Hello Consumer");
    
  4. Supplier
    Represents a supplier of results, without any input parameters.

    Supplier randomValue = () -> Math.random();
    System.out.println(randomValue.get());
    
  5. Comparator
    Used to compare two objects.

    Comparator compare = (a, b) -> a - b;
    System.out.println(compare.compare(5, 3)); // 2
    

Valid and Invalid Lambda Expressions

Let us evaluate some expressions:

  1. () -> {}; → Valid (no parameters, empty body).
  2. () -> "Hello"; → Valid (returns a string directly).
  3. () -> { return "Hello"; }; → Valid (return inside a block).
  4. (Integer i) -> { return "Test" + i; }; → Valid (parameter with type).
  5. (String s) -> { return "Test"; }; → Valid (parameter unused, still correct).
  6. () -> { return "Hello" } → Invalid (missing semicolon inside block).
  7. x -> { return x + 1; } → Context-dependent. Invalid if the type of x cannot be inferred.
  8. (int x, y) -> x + y → Invalid. If one parameter has an explicit type, all must have explicit types.

Advantages of Lambda Expressions

  • More concise and readable code.
  • Eliminates unnecessary anonymous inner classes.
  • Enables functional programming in Java.
  • Used extensively in Streams API for operations like map(), filter(), and forEach().
  • Improves productivity by reducing boilerplate code.

Conclusion

Lambda expressions are one of the most important features introduced in Java 8. They allow developers to write clean, concise, and flexible code by implementing functional interfaces directly. They form the foundation for many modern Java features, including the Streams API and functional programming style.

Mastering lambda expressions is essential for writing efficient Java programs and is a stepping stone towards advanced features like Streams, Optional, and reactive programming.

 

Next Blog- Java Functional Interfaces    

Sanjiv
0

You must logged in to post comments.

Get In Touch

123 Street, New York, USA

+012 345 67890

techiefreak87@gmail.com

© Design & Developed by HW Infotech