Lambdas & Functional Interfaces
From anonymous classes to lambdas, the core functional interfaces, and method references.
Deutsche Übersetzung in Arbeit
Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.
Auf dieser Seite
In older Java, passing behavior around meant writing clunky anonymous classes. Lambdas changed everything: they let you treat a piece of code as a value you can store, pass, and run. They're the foundation of modern, functional-style Java.
From anonymous class to lambda
Suppose you want to run some code on a button click or a new thread. Before lambdas, you wrote a whole anonymous class:
// The old way - lots of ceremony
Runnable task = new Runnable() {
@Override
public void run() {
System.out.println("Working...");
}
};A lambda expresses the same thing in one line:
// The lambda way
Runnable task = () -> System.out.println("Working...");Both create an object with a single method. The lambda just strips away the
boilerplate, leaving only what matters: the parameters () and the body.
Instead of writing a full formal letter (anonymous class) to say "print this",
you jot a quick sticky note: () -> print. You can hand that note to anyone -
a thread, a button, a list - and they'll carry out the instruction. A lambda is
a small, passable packet of behavior.
Lambda syntax
() -> System.out.println("hi") // no parameters
x -> x * 2 // one parameter
(a, b) -> a + b // two parameters
(x, y) -> { // block body with return
int sum = x + y;
return sum;
}Functional interfaces
A lambda can be used wherever a functional interface is expected - an interface with exactly one abstract method. That single method's signature defines what the lambda must look like.
@FunctionalInterface
interface Transformer {
int apply(int value);
}
Transformer doubler = x -> x * 2;
System.out.println(doubler.apply(5)); // 10The @FunctionalInterface annotation is optional but signals intent and makes the
compiler enforce the single-method rule.
The built-in functional interfaces
Java provides ready-made functional interfaces in java.util.function - you'll
use these constantly:
| Interface | Shape | Purpose |
|---|---|---|
Function<T,R> | T -> R | Transform a value |
Predicate<T> | T -> boolean | Test a condition |
Consumer<T> | T -> void | Do something with a value |
Supplier<T> | () -> T | Produce a value |
Function<String, Integer> length = s -> s.length();
Predicate<Integer> isEven = n -> n % 2 == 0;
Consumer<String> printer = s -> System.out.println(s);
Supplier<Double> random = () -> Math.random();
System.out.println(length.apply("hello")); // 5
System.out.println(isEven.test(4)); // true
printer.accept("hi"); // hiMethod references: even shorter
When a lambda just calls an existing method, a method reference (::) is
cleaner:
Consumer<String> print = System.out::println; // same as s -> System.out.println(s)
Function<String, Integer> len = String::length; // same as s -> s.length()
List.of("a", "b", "c").forEach(System.out::println);Read :: as 'use this method as the behavior'
System.out::println means "use println as the behavior". Method references
are just a tidy shorthand for lambdas that do nothing but call one existing
method. Use them when they read more clearly than the equivalent lambda.
Why this matters
Lambdas make behavior a first-class value. That unlocks the Stream API (next lesson), cleaner event handling, and the whole functional style - writing what you want done rather than a manual loop describing how.
Quick check
What defines a 'functional interface' - the kind a lambda can implement?
Key takeaways
- A lambda is a concise, passable packet of behavior: (params) -> body.
- Lambdas replace verbose anonymous classes for single-method interfaces.
- A functional interface has exactly one abstract method; a lambda implements it.
- Key built-ins: Function (transform), Predicate (test), Consumer (use), Supplier (produce).
- Method references (Class::method) are a clean shorthand for lambdas that just call one method.
Next, we'll explore the mindset behind lambdas - the core principles of functional programming in Java.