Course outline · 0% complete

0/29 lessons0%

Course overview →

Lambdas

lesson 9-1 · ~11 min · 24/29

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:

InterfaceMethodMeaning
Predicate<T>test(T) → booleana yes/no question
Consumer<T>accept(T) → voiddo something with it
Function<T, R>apply(T) → Rtransform T into R
Supplier<T>get() → Tproduce 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.