How to Pass Lambda Expression as a Parameter in Java 8

Introduction

Lambda expressions, introduced in Java 8, allow you to write concise and functional code. They provide a clean and efficient way to pass behavior (functions) as arguments to methods. In this guide, we will explore how to pass lambda expressions as parameters in Java 8.

Problem Statement

Write a Java program that:

  • Defines a method that accepts a lambda expression as a parameter.
  • Passes a lambda expression to the method.
  • Executes the lambda inside the method.

Example:

  • Input: A lambda expression for a custom operation.
  • Output: The result of executing the lambda inside the method.

Solution Steps

  1. Define a Functional Interface: Create a functional interface with a single abstract method.
  2. Create a Method that Accepts Lambda: Write a method that accepts the functional interface as a parameter.
  3. Pass the Lambda Expression: Pass the lambda expression to the method, and it will be executed inside the method.

Example 1: Passing Lambda for Arithmetic Operation

Let’s create a program that accepts a lambda expression for performing an arithmetic operation (like addition or multiplication).

Step 1: Define a Functional Interface

@FunctionalInterface
interface MathOperation {
    int operate(int a, int b);  // Abstract method for the lambda expression
}

Step 2: Create a Method that Accepts Lambda

public class LambdaAsParameter {
    // Method that accepts a lambda expression for a MathOperation
    public static int executeOperation(int a, int b, MathOperation operation) {
        return operation.operate(a, b);  // Execute the lambda expression
    }

    public static void main(String[] args) {
        // Step 3: Pass lambda expression for addition
        MathOperation addition = (x, y) -> x + y;
        int sum = executeOperation(5, 3, addition);
        System.out.println("Addition: " + sum);

        // Step 3: Pass lambda expression for multiplication
        MathOperation multiplication = (x, y) -> x * y;
        int product = executeOperation(5, 3, multiplication);
        System.out.println("Multiplication: " + product);
    }
}

Output

Addition: 8
Multiplication: 15

Explanation

  • Functional Interface MathOperation: This defines a single abstract method operate(), which takes two integers and returns an integer. This serves as the template for lambda expressions.
  • executeOperation(): This method accepts two integers and a MathOperation (lambda expression) as parameters. The lambda is executed inside the method.
  • Passing Lambdas: In the main method, we pass different lambda expressions for addition and multiplication to the executeOperation() method.

Example 2: Passing Lambda for Custom String Operation

Let’s explore another example where we pass a lambda expression for custom string operations.

Step 1: Define a Functional Interface for String Operation

@FunctionalInterface
interface StringOperation {
    String modify(String str);
}

Step 2: Create a Method that Accepts the Lambda

public class LambdaAsStringParameter {
    // Method that accepts a lambda for string operations
    public static String executeStringOperation(String str, StringOperation operation) {
        return operation.modify(str);  // Execute the lambda expression
    }

    public static void main(String[] args) {
        // Pass lambda to convert string to uppercase
        StringOperation toUpperCase = s -> s.toUpperCase();
        String result1 = executeStringOperation("hello", toUpperCase);
        System.out.println("Uppercase: " + result1);

        // Pass lambda to reverse the string
        StringOperation reverse = s -> new StringBuilder(s).reverse().toString();
        String result2 = executeStringOperation("hello", reverse);
        System.out.println("Reversed: " + result2);
    }
}

Output

Uppercase: HELLO
Reversed: olleh

Explanation

  • Functional Interface StringOperation: This defines a method modify() that takes a string and returns a modified string.
  • executeStringOperation(): This method accepts a string and a lambda expression for modifying the string.
  • Passing Lambdas: In the main method, we pass different lambda expressions to convert a string to uppercase and to reverse a string.

Example 3: Passing Lambda for Custom Object Operations (Using Employee Class)

In this example, we’ll pass a lambda to perform operations on Employee objects.

Step 1: Define a Functional Interface for Employee Operation

@FunctionalInterface
interface EmployeeOperation {
    void apply(Employee employee);
}

Step 2: Define the Employee Class

class Employee {
    private String name;
    private int salary;

    public Employee(String name, int salary) {
        this.name = name;
        this.salary = salary;
    }

    public void giveRaise(int amount) {
        this.salary += amount;
    }

    @Override
    public String toString() {
        return name + " (Salary: " + salary + ")";
    }
}

Step 3: Create a Method that Accepts the Lambda

public class LambdaWithEmployee {
    // Method that accepts a lambda to apply an operation on an Employee
    public static void applyEmployeeOperation(Employee employee, EmployeeOperation operation) {
        operation.apply(employee);  // Execute the lambda expression
    }

    public static void main(String[] args) {
        Employee emp = new Employee("John", 50000);

        // Pass lambda to give a raise
        EmployeeOperation giveRaise = e -> e.giveRaise(5000);
        applyEmployeeOperation(emp, giveRaise);
        System.out.println("After raise: " + emp);

        // Pass lambda to print employee details
        EmployeeOperation printDetails = e -> System.out.println("Employee Details: " + e);
        applyEmployeeOperation(emp, printDetails);
    }
}

Output

After raise: John (Salary: 55000)
Employee Details: John (Salary: 55000)

Explanation

  • Functional Interface EmployeeOperation: This interface defines a method apply() that operates on an Employee object.
  • applyEmployeeOperation(): This method accepts an Employee object and a lambda expression to perform an operation on the employee.
  • Passing Lambdas: We pass different lambda expressions to give a raise and print employee details.

Conclusion

Lambda expressions in Java 8 can be passed as parameters to methods, providing a clean and efficient way to pass behavior (functions) as arguments. By defining functional interfaces and using lambda expressions, you can customize method behavior at runtime. This approach is particularly useful in scenarios where you need to pass different operations dynamically to methods.

Comments