Lambda Syntax
Lambda Syntax
In the previous lesson you saw how anonymous classes let you pass behaviour as a value. Lambdas are a cleaner spelling of the same idea. This lesson digs into every part of the syntax: how parameters are written, when you can drop parentheses and type annotations, and the difference between an expression body and a block body.
The Shape of a Lambda
A lambda expression has three parts separated by the arrow token ->:
The left side declares what the lambda receives. The right side declares what it does. There is no return type, no access modifier, no name.
Parameter Lists
Parameter syntax is flexible. The rules are:
- Zero parameters — write empty parentheses:
() -> ... - One parameter — parentheses are optional if you omit the type:
x -> ...or(x) -> ... - Two or more parameters — parentheses are required:
(a, b) -> ... - Explicit types — parentheses are required:
(String s) -> ...
Type Inference
In almost every real-world lambda you omit the parameter types. The compiler infers them from the target type — the functional interface the lambda is being assigned to or passed into. This is the same flow-sensitive inference Java uses for var and generic method calls.
When there is genuine ambiguity — for example, when a method is overloaded with incompatible functional interfaces — the compiler asks you to add explicit types to resolve it. That situation is rare.
Expression Bodies
If the lambda body is a single expression, the result of that expression is the implicit return value. No braces, no return keyword.
Expression bodies shine for small transformations, comparisons, and predicates. Keep them as expressions whenever the logic fits on one line.
Block Bodies
When you need more than one statement — local variables, conditionals, loops — wrap the body in braces. You must then use an explicit return statement for non-void lambdas.
Return Inside a Block Body
A common mistake is forgetting that return inside a lambda exits the lambda, not the surrounding method.
list.add(item) returns boolean, but you can use it as the body of a Consumer<T> lambda — Java simply discards the return value. The compiler calls this a void-compatible expression.
Putting It Together: Sorting Example
Comparator is one of the oldest functional interfaces in Java. Sorting a list by string length shows all syntax variants side by side:
Summary
Lambda syntax revolves around three choices: how many parameters (and whether to write their types), whether to use an expression body or a block body, and whether to include parentheses around a single untyped parameter. The compiler infers types from the target functional interface, so you almost never need to spell them out. Use expression bodies for concise single-expression logic and block bodies when you need multiple statements — and consider extracting long block bodies into named methods.