Lambda expressions provide a shorter way of writing an implementation of a method for later. They are also known as closures or anonymous methods.
This feature was introduced in Java 8 to replace the "vertical problem" of anonymous classes, using a lots of code lines to only represent a single call to a method, for example.
Runnable r = new Runnable() {
public void run() {
System.out.println("Howdy, world!");
}
};
Runnable r = () -> System.out.println("Howdy, world!");
The syntax of a lambda expression is:
(formal parameter list) -> { expression or statements }
(x, y) -> x + y
(x, y) -> {
return x + y;
}
(int x, int y) -> {
return x + y;
}
A comma-separated list of formal parameters that match the formal parameters of the single method in a functional interface
Specifying the parameter types is optional (they can be inferred from the context).
(x, y) -> x + y
The parameter list must be enclosed within parentheses except when a single parameter is specified without its type.
(int x, int y) -> x + y
(int x) -> x * 2
x -> x * 2
If there are no parameters, empty parentheses must be specified.
() -> System.out.println("Hello lambdas")
The lambda body has a result that must be one of the following:
void
, if the functional interface method result is void
The lambda body result is returned according to one of the following options.
If a single expression is used, the expression value is returned.
(int x, int y) -> x + y
If a statement block is used and the method has a return type, a return statement must be used.
(int x, int y) -> {
x++;
y++;
return x + y;
}
If the functional interface method result is void
, return statements are optional.
When a lambda expression is invoked, the code in the lambda body is executed.
Here is an example of how we can use lambda expressions with forEach()
methods to apply operations on all elements of a collection.
public class Main {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("Reverse Giraffe", "parasite");
map.put("Morty", "person");
map.put("Sleepy Gary", "parasite");
map.put("Beth", "person");
map.put("Hamuray", "parasite");
map.keySet().forEach(
character -> System.out.println(character + ": I'm real!"));
map.keySet().forEach(
(character) -> System.out.println(character + ": Are you real?"));
map.forEach(
(character, nature) -> System.out.println(character + ": I'm a " + nature));
map.forEach(
(String character, String nature) -> System.out.println(character + ": I'm a " + nature));
map.forEach(
(character, nature) -> {
if (nature.equals("person")) {
System.out.println(character + ": Kill the parasites!");
}
});
}
}
Here is another example of the use of lambda expressions. This time we are calculating the sum and the product of all numbers in an array.
public class IntReturn {
public static void main(String[] args) {
int[] values = {1, 2, 3, 4};
int sum = reduce(values, 0, (x, y) -> x + y);
System.out.println("Sum: " + sum);
int product = reduce(values, 1, (x, y) -> x * y);
System.out.println("Product: " + product);
int sumOfSquares =
reduce(
values,
0,
(x, y) -> {
int ySquared = (int) Math.pow(y, 2);
return x + ySquared;
});
System.out.println("Sum of squares: " + sumOfSquares);
}
static int reduce(int[] array, int initial, BinaryOperator<Integer> operator) {
for (int value : array) {
initial = operator.apply(initial, value);
}
return initial;
}
}