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