Lambda syntax, from long to short¶
โ Java 17 ยท Passing Behavior Around with Lambdas ยท 2/3
A lambda is code you pass to a method, matched to the method's interface. Here's how to write one correctly.
Anatomy¶
| Part | Role |
|---|---|
| Parameters (left) | m, or with its type: (Movie m) |
Arrow -> |
separates parameters and body; exactly one per lambda |
| Body (right) | one expression whose value is returned, or a block { โฆ } of statements |
Trimming it down¶
(Movie m) -> { return m.isNew(); } // full form
(Movie m) -> m.isNew() // no braces, no return, no ;
m -> m.isNew() // no type, no parentheses
m -> { return m.isNew(); } // mix and match: valid
(m) -> m.isNew() // parentheses kept: valid
Two rules:
- Parentheses can be dropped only for exactly one parameter without a type. With a type, or with zero or several parameters, they're required.
- Braces are all or nothing. Without braces: no
return, no;. With braces: you writereturn(if a value is expected) and end every statement with;.
m -> {} is valid too: an empty block, for a method that returns nothing.
Shapes that compile¶
() -> true // 0 parameters: () required
t -> t.startsWith("Star") // 1 parameter
(String t) -> t.startsWith("Star") // 1, typed: () required
(t, g) -> { return t.startsWith("Dark"); } // 2 parameters
(String t, String g) -> t.startsWith("Dark") // 2, typed
The last two never use g: a lambda doesn't have to use every parameter.
Spot the broken lambda¶
| โ Doesn't compile | โ Fixed | Problem |
|---|---|---|
t, g -> t.startsWith("Dark") |
(t, g) -> t.startsWith("Dark") |
two parameters need () |
t -> { t.startsWith("Dark"); } |
t -> { return t.startsWith("Dark"); } |
braces need return |
t -> { return t.startsWith("Dark") } |
t -> t.startsWith("Dark") |
missing ; inside braces |
String t -> t.endsWith("Mirror") |
(String t) -> t.endsWith("Mirror") |
a typed parameter needs () |
var can't hold a lambda¶
var rule = (Movie m) -> m.isNew(); // โ doesn't compile
MovieFilter rule = m -> m.isNew(); // โ
the type gives the context
print(catalog, rule); // store it now, use it later
var infers its type from the value; a lambda infers its type from where it goes. With var, each waits for the other. Declare the variable with a real interface type, and the lambda becomes a value you can store, pass and reuse.
The lab uses one method and a lambda per row to build a streaming home screen.