Skip to content

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

m -> m.isNew()                        // shortest form
(Movie m) -> { return m.isNew(); }    // longest form, same behavior
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 write return (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.

๐Ÿ’ป Code: Java17_Part_8_Functional_Programming on GitHub

โ† From class to lambda ยท Next: the lab โ†’