Quiz
Warm-up from lesson 6-3: the Instrument interface declared exactly one method, play(). Why does that shape of interface matter for this unit?
Functions as values
Python lets you pass functions around: sorted(names, key=len). For its first two decades Java could not — passing one line of behavior meant declaring a whole class around it. Here is what "sort by length" cost before 2014, versus the lambda (a compact anonymous function) that Java 8 introduced:
// the old way: an anonymous class, 5 lines of ceremony for 1 line of logic names.sort(new Comparator<String>() { public int compare(String a, String b) { return a.length() - b.length(); } }); // the lambda way names.sort((a, b) -> a.length() - b.length());
Lambdas exist to make behavior as easy to hand around as data — the whole streams toolkit in the next lesson is built on that. The shapes:
n -> n * 2 // one parameter, returns n * 2 (a, b) -> a + b // two parameters s -> { // multi-statement body needs braces + return String t = s.trim(); return t.length(); }
A lambda's type is always some functional interface, an interface with exactly one abstract method. The collections you already know accept them directly:
names.removeIf(n -> n.length() > 4); // takes a Predicate<String> names.forEach(n -> System.out.println(n)); // takes a Consumer<String> nums.sort((a, b) -> a - b); // takes a Comparator<Integer>
Code exercise · java
Run this. removeIf drops every name longer than 4 characters, then forEach prints the survivors uppercased. No explicit loop anywhere.
The core functional interfaces
Four shapes from java.util.function cover most lambda uses:
| Interface | Method | Meaning |
|---|---|---|
Predicate<T> | test(T) → boolean | a yes/no question |
Consumer<T> | accept(T) → void | do something with it |
Function<T, R> | apply(T) → R | transform T into R |
Supplier<T> | get() → T | produce a value |
You rarely name these types, you just hand a lambda to a method that expects one. One more shorthand: a method reference like System.out::println means "the lambda that just calls this method", so names.forEach(System.out::println) works too.
Code exercise · java
Your turn. Given the numbers list, use removeIf with a lambda to delete every even number (recall n % 2 from lesson 3-1), sort ascending with a comparator lambda (a, b) -> a - b, then print each remaining number on its own line with forEach.