Home ยป Java Lambda Expressions

Java Lambda Expressions

Java Lambda Expressions, introduced in Java 8, provide a clear and concise way to represent one method interface using an expression.

They are particularly useful for functional interfaces, which are interfaces with a single abstract method.

Lambda expressions help simplify code by eliminating the need for anonymous classes, making code more readable and easier to maintain.

Syntax of Lambda Expressions

The syntax of a lambda expression is:

(parameters) -> expression
(parameters) -> { statements; }
  • (parameters): The input parameters for the method.
  • ->: The arrow token separates parameters from the expression or block of code.
  • expression or { statements; }: The body of the lambda expression, which can either be a single expression or a block of statements.

Key Points about Lambda Expressions

  1. Functional Interface Requirement: Lambda expressions can only be used with functional interfaces.
  2. Type Inference: The types of parameters can be inferred by the compiler.
  3. Conciseness: Lambdas simplify code by reducing boilerplate syntax.

Example 1: Basic Lambda Expression with Runnable

The Runnable interface is a functional interface with a single run() method, which is ideal for a lambda expression.

Example

public class LambdaRunnableExample {
    public static void main(String[] args) {
        // Using lambda expression for Runnable
        Runnable task = () -> System.out.println("Task is running");
        
        // Start a thread with the lambda expression
        Thread thread = new Thread(task);
        thread.start();
    }
}

Explanation

  • We create a Runnable using a lambda expression instead of an anonymous inner class.
  • Runnable task = () -> System.out.println(“Task is running”); represents the run() method of Runnable.

Output

Task is running

Example 2: Lambda Expression with Parameters

This example uses a lambda expression with parameters in the Comparator interface to compare two strings by their lengths.

Example

import java.util.Arrays;
import java.util.Comparator;

public class LambdaComparatorExample {
    public static void main(String[] args) {
        String[] names = { "John", "Alice", "Bob", "Charlie" };
        
        // Using lambda expression to sort by string length
        Arrays.sort(names, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
        
        // Display sorted array
        System.out.println(Arrays.toString(names));
    }
}

Explanation

  • (s1, s2) -> Integer.compare(s1.length(), s2.length()) is a lambda expression that implements the compare method of Comparator<String>.
  • This lambda expression sorts strings by their lengths.

Output

[Bob, John, Alice, Charlie]

Example 3: Using Lambda with Custom Functional Interface

You can define your own functional interface to use with lambda expressions.

Example

@FunctionalInterface
interface Greeting {
    void sayHello(String name);
}

public class LambdaCustomInterfaceExample {
    public static void main(String[] args) {
        // Lambda expression for Greeting interface
        Greeting greeting = name -> System.out.println("Hello, " + name + "!");
        
        // Use the lambda expression
        greeting.sayHello("Alice");
        greeting.sayHello("Bob");
    }
}

Explanation

  • Greeting is a custom functional interface with a single method sayHello.
  • name -> System.out.println(“Hello, ” + name + “!”) is a lambda that implements sayHello to greet a user by name.

Output

Hello, Alice!
Hello, Bob!

Example 4: Lambda Expression with Block of Statements

If the lambda body has multiple statements, enclose them in curly braces { }.

Example

@FunctionalInterface
interface MathOperation {
    int operate(int a, int b);
}

public class LambdaBlockExample {
    public static void main(String[] args) {
        // Lambda expression with multiple statements in the body
        MathOperation addition = (a, b) -> {
            System.out.println("Adding " + a + " and " + b);
            return a + b;
        };
        
        int result = addition.operate(5, 3);
        System.out.println("Result: " + result);
    }
}

Explanation

  • (a, b) -> { System.out.println(“Adding ” + a + ” and ” + b); return a + b; } has a block of statements within the lambda.
  • The lambda prints each operand before performing the addition.

Output

Adding 5 and 3
Result: 8

Example 5: Lambda Expressions with Predicate Functional Interface

The Predicate<T> interface is a generic functional interface that accepts a single argument and returns a boolean result. Itโ€™s commonly used in filter operations.

Example

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

public class LambdaPredicateExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");

        // Predicate to check if a string starts with "A"
        Predicate<String> startsWithA = s -> s.startsWith("A");

        // Filter and print names starting with "A"
        names.stream()
             .filter(startsWithA)
             .forEach(System.out::println);
    }
}

Explanation

  • Predicate<String> startsWithA = s -> s.startsWith(“A”) checks if a string starts with “A”.
  • filter(startsWithA) filters the stream to include only names that start with “A”.

Output

Alice

Example 6: Using Lambda with Function Interface

The Function<T, R> interface is a functional interface that accepts one argument of type T and returns a result of type R.

Example

import java.util.function.Function;

public class LambdaFunctionExample {
    public static void main(String[] args) {
        // Function to calculate the square of an integer
        Function<Integer, Integer> square = x -> x * x;

        // Use the function
        System.out.println("Square of 5: " + square.apply(5));
        System.out.println("Square of 10: " + square.apply(10));
    }
}

Explanation

  • Function<Integer, Integer> square = x -> x * x; is a lambda that calculates the square of a number.
  • apply is called with the argument to calculate and print the square.

Output

Square of 5: 25
Square of 10: 100

Example 7: Method References with Lambda Expressions

Java provides method references as a shorthand notation for lambdas that call a single method. They are often used to refer to existing methods or constructors.

Example

import java.util.Arrays;
import java.util.List;

public class LambdaMethodReferenceExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

        // Method reference instead of lambda expression
        names.forEach(System.out::println);
    }
}

Explanation

  • System.out::println is a method reference that refers to System.out.println(String).
  • This replaces a lambda that would have called println on each name in the list.

Output

Alice
Bob
Charlie

Example 8: Lambda Expression with BiFunction

The BiFunction<T, U, R> functional interface takes two arguments of types T and U, and returns a result of type R.

Example

import java.util.function.BiFunction;

public class LambdaBiFunctionExample {
    public static void main(String[] args) {
        // BiFunction to concatenate two strings with a space
        BiFunction<String, String, String> concatenate = (s1, s2) -> s1 + " " + s2;

        // Use the BiFunction
        String result = concatenate.apply("Hello", "World");
        System.out.println("Concatenated String: " + result);
    }
}

Explanation

  • (s1, s2) -> s1 + ” ” + s2 is a lambda that concatenates two strings with a space in between.
  • The apply method is called to concatenate “Hello” and “World”.

Output

Concatenated String: Hello World

Summary

Java lambda expressions simplify working with functional interfaces, making code more concise and readable.

Key points include:

  • Syntax: (parameters) -> expression or (parameters) -> { statements }.
  • Functional Interfaces: Lambdas work with interfaces that have a single abstract method.
  • Common Functional Interfaces:
    • Runnable, Comparator, Predicate, Function, BiFunction, etc.
  • Method References: Provide a shorthand for lambdas that only call one method.

Lambda expressions are a core feature for functional programming in Java, making it easier to work with collections, streams, and functional interfaces.

You may also like