In Part 1 of this article, we had taken a look at functional interfaces. We had seen how functional interfaces along with lambda expressions help to make Java code shorter. In this article, we will be taking a closer look at lambda expressions, understand what they are, and learn the different ways of using them.

  1. What are lambda expressions
  2. Lambda expression Syntax
  3. How to use lambda expressions
  4. Lambda Expression Examples
  5. Why should you use Lambda Expressions?

Java 8 Lambda Expressions

What are lambda expressions

A lambda expression is just like a method. So, it can accept any parameters and return any value. However, unlike other methods, it does not have a method name. It is used to implement the abstract method within a functional interface. Since a lambda expression is a method without a method name, it is also known as an anonymous function.

Lambda expression Syntax

A lambda expression has the following syntax:

(parameters) -> lambda body;

Parameters

Parameters are the values passed into the lambda expression. The lambda expression can accept zero or more parameters. Parameters need to be specified in parentheses. If the lambda expression does not accept any parameters, an empty parenthesis needs to be specified. If the lambda expression accepts a single parameter, the parentheses may be skipped. The data type of the parameters is optional, if it is not specified, it is inferred based on the value passed in. If there are multiple parameters, then they need to be separated by commas.

Lambda operator

-> is known as the lambda operator.

Body of the lambda expression

Any code placed in curly brackets after the lambda operator constitutes the body of the lambda expression. If there is a single statement in the body, the curly brackets can be skipped. If the lambda expression returns a value, the return keyword may be used, but again it is optional and may be skipped if the body of the lambda expression consists of a single statement.

How to use lambda expressions

As mentioned earlier, a lambda expression is used in conjunction with a functional interface to implement the abstract method within a functional interface.

Sample Code

@FunctionalInterface
public interface Reader {
 public void read();
}
  • This code defines a functional interface called Reader
  • Line 3 specifies an abstract method called read
public class ReaderDemo {
 public static void main(String[] args) {
  Reader excelReader = () -> System.out.println("Reading Excel File");
  excelReader.read();
 }
}
  • This code defines a class called ReaderDemo.
  • Line 3 defines a Reader instance called excelReader and assigns it a lambda expression.
  • This means that the specified lambda expression will be used to implement the read method in the Reader interface.
  • Since the read method does not accept any parameters, empty parentheses are specified and the lambda expression body consists of a single System.out.println statement
  • Line 4 invokes the read method. This causes the code within the lambda expression to be executed.

Output

Reading Excel File

Lambda Expression Examples

Let us now take a look at some different examples of lambda expressions.

Single Parameter, No Return Value

The following code demonstrates a lambda expression that accepts a single parameter and does not return any value.

@FunctionalInterface
public interface Operator {
 public void operate(int num);
}
  • This code specifies a functional interface called Operator with an abstract method called operate
  • operate method accepts an int parameter and returns a void
public class OperatorDemo {
 public static void main(String[] args) {
  Operator op = num -> System.out.println("Increasing num by 2:"+(num+2));
  op.operate(10);
 }
}
  • This code specifies a class called OperatorDemo
  • Line 3 uses a lambda expression to implement the operate method in Operator. Since operate accepts a single parameter, the lambda expression also accepts a single parameter called num.
  • The body of the lambda expression consists of a System.out.println statement that increments the input value by 2 and prints it.
    Line 4 invokes the operate method with the value 10. This causes the code within the lambda expression to be executed.

Output

Increasing num by 2:12

Multiple Parameters and Return Value

The following code demonstrates a lambda expression that accepts two parameters and returns a value

@FunctionalInterface
public interface Operator {
 public int operate(int num1,int num2);
}
  • As before, this code specifies a functional interface called Operator with an abstract method called operate
  • The operate method accepts two int parameters and returns an int result
public class OperatorDemo {
 public static void main(String[] args) {
  Operator op = (num1,num2) -> num1+num2;
  int sum = op.operate(10,20);
  System.out.println("sum:"+sum);
 }
}
  • This code specifies a class called OperatorDemo
  • Line 3 uses a lambda expression to implement the operate method in Operator. Since operate accepts two parameters, the lambda expression also accepts two parameters called num1 and num2. Note that they are specified in parentheses
  • The body of the lambda expression simply adds the two input numbers and returns the result. Note that the return keyword is not explicitly specified, since the lambda expression body consists of a single statement, it is implied
  • Line 4 invokes the operate method with the values 10 and 20. This causes the code within the lambda expression to be executed.

Output

sum:30

Why should you use Lambda Expressions?

In addition to making the code concise and easier to read, Lambda expression have several benefits which make using them very beneficial

Providing Different Implementations at Runtime

Lambda expressions allow providing different implementations for the same functional interface method at runtime.

Sample Code

@FunctionalInterface
public interface Operator {
 public int operate(int num1,int num2);
}

As before, this code specifies a functional interface called Operator with an abstract method called operate that accepts two int arguments and returns an int result

public class OperatorDemo {
 public static void main(String[] args) {
  Operator op = (num1,num2) -> num1+num2;
  int sum = op.operate(10,20);
  System.out.println("sum:"+sum);

  Operator op2 = (num1,num2) -> num1-num2;
  int difference = op2.operate(25, 10);
  System.out.println("Difference:"+difference);
 }
}
  • This code specifies a class called OperatorDemo
  • Line 3 declares an Operator instance called op and implements it using a lambda expression that adds the input numbers and returns the result
    Line 7 declares an Operator instance called op2 and implements it using a lambda expression that subtracts num2 from num1 and returns the result
  • So the same functional interface that is Operator is implemented using different lambda expressions, one causes the input arguments to be added while the other causes the input arguments to be subtracted

Output

sum:30
Difference:15

For-each Support

Java 8 has added a new method called forEach to all the Collection interfaces. This allows iterating internally over a Collection without having to write an explicit for loop. The forEach method accepts as a parameter a Consumer instance which is an in-built functional interface and can be implemented via a lambda expression.

Sample Code

Set languages = Set.of("Java","Ruby","Python","C");
languages.forEach(language -> System.out.println("language is:"+language));
  • Line 1 declares and initializes a new Set called languages
  • Line 2 invokes the forEach method on languages with a lambda expression corresponding to the Consumer interface

Output

language is:Java
language is:Ruby
language is:Python
language is:C

Conclusion

So, in this article, we understand what lambda expressions are. We took a close look at the syntax of lambda expressions. We saw some examples of lambda expressions. Finally, we saw some of the benefits of lambda expressions.