Declaring lambda parameters¶
โ Java 17 ยท How Lambdas See the Variables Around Them ยท 1/4
Parameters are the values a lambda receives when it runs. You can declare them in three ways.
Three styles¶
Predicate<Movie> a = m -> m.isAvailable(); // no type
Predicate<Movie> b = (var m) -> m.isAvailable(); // var
Predicate<Movie> c = (Movie m) -> m.isAvailable(); // real type
Predicate<Movie> d = var m -> m.isAvailable(); // โ does not compile
All three valid lines do the same thing. The difference is the parentheses:
- No type: with exactly one parameter, the parentheses are optional.
var: Java infers the type, but the parentheses become mandatory.- Real type: the parentheses are mandatory, and the type must match what the interface expects.
Parentheses can disappear only for a single parameter with no type at all.
Where the type comes from¶
With no type or var, Java reads the type from the context, the place where the lambda is used:
Predicate<User> adult = u -> u.age() >= 18; // the variable: u is a User
void watch(Consumer<Episode> c, Episode e) { c.accept(e); }
watch((var ep) -> ep.play(), pilot); // the method: ep is an Episode
void sort(List<String> titles) {
titles.sort((var a, var b) -> a.compareTo(b)); // the list: a and b are Strings
}
To find a parameter's type, ask: what is this lambda assigned to, or passed to?
One style per lambda¶
All the parameters of one lambda use the same style:
| โ Mixed | โ Consistent |
|---|---|
(var t, r) -> t.isEmpty() |
(t, r) -> t.isEmpty() |
(var t, String r) -> true |
(var t, var r) -> true |
(String t, var r, Integer s) -> 1 |
(String t, String r, Integer s) -> 1 |
(Integer s, e) -> "Pilot" |
(Integer s, Integer e) -> "Pilot" |
To fix a mixed list, add var or a type to every parameter, or remove it from all of them. var and real types can't be combined either.
final and annotations¶
Like method parameters, lambda parameters accept modifiers:
Consumer<Episode> c1 = (final var e) -> e.play();
Consumer<Episode> c2 = (@Deprecated Episode e) -> e.play();
titles.sort((final var a, @Deprecated var b) -> a.compareTo(b));
Consumer<Episode> c3 = (final e) -> e.play(); // โ does not compile
final stops the parameter from being reassigned in the body. A modifier needs something to attach to: var or a real type. You'll rarely need this in real code.
Parameters are what the lambda receives. Next: what it creates inside its own body.