Java Lambda Expressions

Functional programming with concise syntax

⚡ What are Lambda Expressions?

Lambda expressions provide a concise way to represent anonymous functions. They enable functional programming style and make code more readable and maintainable.


// Traditional way
Runnable r1 = new Runnable() {
    public void run() { System.out.println("Hello"); }
};

// Lambda expression
Runnable r2 = () -> System.out.println("Hello");
                                    

Output:

Both print: Hello

Lambda is much more concise!

Lambda Features

📝

Syntax

Concise function syntax

(parameters) -> expression
🎯

Functional Interface

Single abstract method

@FunctionalInterface
interface Calculator { }
🔄

Stream API

Works with collections

list.stream().filter(x -> x > 5)
⚙️

Method Reference

Shorthand for lambdas

String::toUpperCase

🔹 Lambda Syntax Examples

Different forms of lambda expressions:

import java.util.function.*;

public class LambdaSyntax {
    public static void main(String[] args) {
        
        // No parameters
        Runnable r = () -> System.out.println("Hello World");
        r.run();
        
        // Single parameter (parentheses optional)
        Consumer<String> printer = message -> System.out.println(message);
        printer.accept("Lambda with single parameter");
        
        // Multiple parameters
        BinaryOperator<Integer> add = (a, b) -> a + b;
        System.out.println("Sum: " + add.apply(5, 3));
        
        // Multiple statements (braces required)
        Function<String, String> processor = (input) -> {
            String processed = input.toUpperCase();
            processed = processed.trim();
            return processed;
        };
        System.out.println(processor.apply("  hello world  "));
        
        // Return type inferred
        Predicate<Integer> isEven = num -> num % 2 == 0;
        System.out.println("Is 4 even? " + isEven.test(4));
    }
}

Output:

Hello World

Lambda with single parameter

Sum: 8

HELLO WORLD

Is 4 even? true

🔹 Functional Interfaces

Common functional interfaces used with lambdas:

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

public class FunctionalInterfaceExample {
    public static void main(String[] args) {
        
        // Predicate - tests a condition
        Predicate<String> isEmpty = str -> str.isEmpty();
        System.out.println("Is empty: " + isEmpty.test(""));
        
        // Function - transforms input to output
        Function<String, Integer> getLength = str -> str.length();
        System.out.println("Length: " + getLength.apply("Hello"));
        
        // Consumer - accepts input, returns nothing
        Consumer<String> print = str -> System.out.println("Message: " + str);
        print.accept("Lambda Consumer");
        
        // Supplier - provides a value
        Supplier<Double> randomValue = () -> Math.random();
        System.out.println("Random: " + randomValue.get());
        
        // UnaryOperator - same input and output type
        UnaryOperator<String> toUpper = str -> str.toUpperCase();
        System.out.println("Upper: " + toUpper.apply("lambda"));
        
        // BinaryOperator - two inputs, same type output
        BinaryOperator<String> concat = (a, b) -> a + " " + b;
        System.out.println("Concat: " + concat.apply("Hello", "World"));
    }
}

Output:

Is empty: true

Length: 5

Message: Lambda Consumer

Random: 0.7234567

Upper: LAMBDA

Concat: Hello World

🔹 Lambda with Collections

Using lambdas with Stream API for collection processing:

import java.util.*;
import java.util.stream.Collectors;

public class LambdaCollections {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // Filter and collect
        List<String> longNames = names.stream()
            .filter(name -> name.length() > 4)
            .collect(Collectors.toList());
        System.out.println("Long names: " + longNames);
        
        // Map transformation
        List<String> upperNames = names.stream()
            .map(name -> name.toUpperCase())
            .collect(Collectors.toList());
        System.out.println("Upper names: " + upperNames);
        
        // Filter and map numbers
        List<Integer> evenSquares = numbers.stream()
            .filter(n -> n % 2 == 0)
            .map(n -> n * n)
            .collect(Collectors.toList());
        System.out.println("Even squares: " + evenSquares);
        
        // Reduce operation
        int sum = numbers.stream()
            .filter(n -> n > 5)
            .reduce(0, (a, b) -> a + b);
        System.out.println("Sum of numbers > 5: " + sum);
        
        // forEach with lambda
        System.out.print("Names: ");
        names.stream()
            .filter(name -> name.startsWith("A") || name.startsWith("B"))
            .forEach(name -> System.out.print(name + " "));
        System.out.println();
    }
}

Output:

Long names: [Alice, Charlie, David]

Upper names: [ALICE, BOB, CHARLIE, DAVID, EVE]

Even squares: [4, 16, 36, 64, 100]

Sum of numbers > 5: 30

Names: Alice Bob

🧠 Test Your Knowledge

What is the lambda expression equivalent of: new Runnable() { public void run() { System.out.println("Hi"); } }?