Lambda Expressions
A lambda is a short way to write behavior
Sometimes a method needs to receive not a ready value, but a rule: how to compare elements, what should count as a matching value, or which action should be performed later. In the past, such behavior often required creating a separate object. A lambda expression lets you describe a small action right where it is used.
For example, Comparator is already familiar from collections.
Instead of a separate comparator class, the sorting rule can be written like this:
Comparator<String> byLength =
(left, right) -> Integer.compare(left.length(), right.length());
The parameters are on the left side of ->, and the lambda body is on the right.
Here the lambda receives two strings and returns the result of comparing their lengths.
The compiler infers the parameter types from Comparator<String>, so they do not have to be written explicitly.
An expression or a block of code
If the action consists of one expression, braces and return are usually unnecessary:
Comparator<String> byLength =
(a, b) -> Integer.compare(a.length(), b.length());
When there are several statements inside, a regular block is used. If the lambda must return a value,
that block needs return.
Comparator<String> byLengthThenText = (a, b) -> {
int result = Integer.compare(a.length(), b.length());
return result != 0 ? result : a.compareTo(b);
};
A lambda gets its type from context
A lambda expression is not a standalone object of some “unknown type.” The compiler must understand which suitable interface it belongs to. That is why the same lambda shape can be used in different places when the expected type defines compatible parameters and a compatible result.
Access to local variables
A lambda can read a local variable from the surrounding method
if that variable is not changed after assignment. Such a variable is called effectively final:
you do not have to write the final keyword,
but the value must remain unchanged.
int minLength = 4;
Comparator<String> byDistance = (a, b) ->
Integer.compare(Math.abs(a.length() - minLength),
Math.abs(b.length() - minLength));
If you later try to assign another value to minLength,
the compiler will not allow that variable to be used inside the lambda.
This rule protects lambdas from ambiguous work with mutable local variables.