Syntax
(parameters) -> expressionExamples
Basic Lambda Syntax
Comparing a lambda to the equivalent anonymous class it replaces.
interface Greeter {
String greet(String name);
}
// Old way: anonymous class
Greeter oldStyle = new Greeter() {
@Override
public String greet(String name) {
return "Hello, " + name;
}
};
// New way: lambda expression
Greeter newStyle = name -> "Hello, " + name;
System.out.println(newStyle.greet("Fola")); // Hello, FolaLambdas with Built-in Functional Interfaces
java.util.function provides ready-made functional interfaces like Function, Predicate, and Consumer.
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Consumer;
Function<Integer, Integer> square = x -> x * x;
System.out.println(square.apply(5)); // 25
Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4)); // true
Consumer<String> printer = s -> System.out.println("Value: " + s);
printer.accept("Hello"); // Value: HelloMulti-Statement Lambdas
A lambda body can contain multiple statements using curly braces and an explicit return.
import java.util.function.Function;
Function<Integer, String> classify = n -> {
if (n < 0) {
return "negative";
} else if (n == 0) {
return "zero";
} else {
return "positive";
}
};
System.out.println(classify.apply(-5)); // negative
System.out.println(classify.apply(0)); // zeroLambdas with sorting
A very common use: passing a lambda as a Comparator to control sort order.
import java.util.ArrayList;
ArrayList<String> names = new ArrayList<>(java.util.List.of("Charlie", "Alice", "Bob"));
names.sort((a, b) -> a.compareTo(b));
System.out.println(names); // [Alice, Bob, Charlie]
names.sort((a, b) -> b.length() - a.length()); // longest name first
System.out.println(names);Best practices
- Use lambdas for short, simple implementations of a functional interface - switch to a full method or class once the logic gets long or complex
- Prefer built-in functional interfaces from java.util.function (Function, Predicate, Consumer, Supplier) over defining your own where possible
- Keep lambda parameter names short but meaningful, especially in stream chains where context is often clear from position
- Remember a lambda can only implement an interface with exactly one abstract method (a functional interface) - not any arbitrary interface
At a glance
- Purpose
- General-purpose application development
- File extension
- .java
- Runs in
- Java Virtual Machine
- Usually used with
- JDK and Java libraries
Specifications & further reading
Related Java documentation
The Stream API, introduced in Java 8, provides a functional, declarative way to process sequences of elements from collections, arrays, or other sources. A stream pipeline consists of a source, zero or more intermediate operations (like filter and map, which are lazy and return a new stream), and exactly one terminal operation (like forEach or collect) that actually triggers processing.Stream Terminal Operations
Terminal operations are what actually trigger a stream pipeline to execute and produce a final result, consuming the stream in the process - after a terminal operation runs, the stream cannot be reused. Common terminal operations include reduce() for combining elements into a single value, count(), sum-style operations for numeric streams, anyMatch()/allMatch() for boolean checks, and findFirst() for retrieving a single element.Collectors
Collectors, used with the stream terminal operation collect(), provide ready-made ways to accumulate stream elements into a final result - a List, Set, Map, a joined String, or grouped/partitioned data. The java.util.stream.Collectors class offers factory methods like toList(), joining(), groupingBy(), and counting() that cover the vast majority of real-world aggregation needs.Optional
Optional<T> is a container object that may or may not hold a non-null value, designed to make the possibility of 'no result' explicit in a method's return type, reducing NullPointerExceptions. Rather than returning null and hoping callers remember to check for it, a method returning Optional<T> signals clearly that a value might be absent, and provides safe methods like isPresent(), ifPresent(), and orElse() for handling both cases.