A lambda is a short, anonymous function.
Before and after
Java
// anonymous class — Java 7 style
Runnable r = new Runnable() {
@Override public void run() {
System.out.println("Running");
}
};
// lambda — Java 8+
Runnable r2 = () -> System.out.println("Running");Syntax
Java
() -> System.out.println("hi") // no parameters
x -> x * 2 // one parameter, parens optional
(x, y) -> x + y // two parameters
(x, y) -> { // block body needs return
int sum = x + y;
return sum * 2;
}Functional interfaces
A lambda can be assigned to any interface with exactly one abstract
method. The standard ones live in java.util.function:
| Interface | Signature | Use |
|---|---|---|
Predicate<T> |
T → boolean |
filtering |
Function<T,R> |
T → R |
transforming |
Consumer<T> |
T → void |
side effects |
Supplier<T> |
() → T |
producing values |
BiFunction<T,U,R> |
(T,U) → R |
two inputs |
Java
Predicate<String> isLong = s -> s.length() > 5;
Function<String, Integer> len = s -> s.length();
Consumer<String> printer = s -> System.out.println(s);
Supplier<Double> random = () -> Math.random();
System.out.println(isLong.test("Kathmandu")); // true
System.out.println(len.apply("Nepal")); // 5
printer.accept("hello");
System.out.println(random.get());Your own functional interface
Java
@FunctionalInterface
interface Calculator {
int apply(int a, int b);
}
Calculator add = (a, b) -> a + b;
Calculator mul = (a, b) -> a * b;
System.out.println(add.apply(3, 4)); // 7The @FunctionalInterface annotation makes the compiler verify there is
exactly one abstract method.
Method references
When a lambda just calls an existing method, use :::
Java
list.forEach(System.out::println); // instead of x -> System.out.println(x)
names.stream().map(String::toUpperCase); // instead of s -> s.toUpperCase()
list.sort(Comparator.comparing(Book::getTitle));
Supplier<List<String>> maker = ArrayList::new; // constructor referenceEffectively final capture
A lambda may use local variables only if they never change:
Java
int factor = 2;
Function<Integer, Integer> f = x -> x * factor; // fine
// factor = 3; ← breaks the lambda above: not effectively finalFields have no such restriction — only local variables.