Lambda
In short: A compact, nameless function (since Java 8) — in many cases replaces a verbose anonymous class when only a single method has to be implemented.
In more detail: Syntax: (parameter) -> expression or (parameter) -> { statements }. Only works with “functional interfaces” (interfaces with exactly one abstract method, e.g. Runnable, Comparator). Often combined with the Streams API to compactly filter, transform, or sort collections.
list.forEach(element -> System.out.println(element));In Depth
@FunctionalInterface // optional but recommended - has the compiler check: exactly 1 abstract method
interface Calculator {
int calculate(int a, int b);
}
Calculator add = (a, b) -> a + b;
Calculator multiply = (a, b) -> a * b;
System.out.println(add.calculate(3, 4)); // 7
// Very often combined with the Streams API
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
List<Integer> evenSquares = numbers.stream()
.filter(n -> n % 2 == 0) // lambda: which numbers to keep
.map(n -> n * n) // lambda: how to transform
.collect(Collectors.toList());
System.out.println(evenSquares); // [4, 16, 36]
// Method reference - even more compact, when the lambda only calls an existing method
numbers.forEach(System.out::println); // instead of numbers.forEach(n -> System.out.println(n))A lambda automatically “inherits” its type from the context in which it’s used (functional interface as the target) — it has no explicitly named type of its own in the code. The combination of filter/map/collect on the Streams API is by far the most common practical use of lambdas in modern Java code: it replaces classic loops with manual collection into a new list with a declarative chain of transformation steps, which is often significantly more compact and less error-prone than the corresponding loop version.
See also: Anonymous Classes, Interface, Sorting