Java 8 Lambda Expression
Lambda expression is a feature of Java language which was introduced in Java 8 version. It is a function that has no name and uses a functional approach to execute code. the lambda expression is also known as an anonymous function.
It is designed to provide the implementation of a functional interface. An interface that has only a single abstract method is known as a functional interface. Java provides an annotation @FunctionalInterface, which is used to declare an interface as a functional interface. For more about Functional interface, read our post on Java Functional Interface.
It uses less code and provides a clear and concise way to represent one method interface. It is very useful in the collection library to iterate, filter, and extract data from the collection.
Advantages of Lambda Expression
-
The body of a lambda expression can have one or more statements.
-
Curly brackets are optional if there is a single statement.
-
The return statement is optional, use only if the method signature has a return type.
-
We can pass zero, one, or more parameters to a lambda expression.
-
The type of parameters can be explicitly declared or it can be inferred from the context.
-
When there is a single parameter, it is not mandatory to use parentheses. Parentheses are optional.
Syntax
(list of arguments) -> { expression body}
list of arguments can be zero, one, or more.
expression body can have one or more statements.
Short Examples of Lambda Expression
We can think of lambda expression as a smart and short way to define a function. If you are a beginner then we recommend you to first read about Function and Functional Interface in Java.
You can get the idea of the lambda expression with the help of given basic examples:
() -> System.out.println("executing lambda expression."); // zero argument, lambda expression
(String str) -> System.out.print(str); // single argumment, lambda expression
(int a, int b) -> a+b; // multiple arguments, sum of two values
(a,b) -> a+b // parameters without types, can be used to sum and concat two strings as well.
(int a, int b) -> return (a+b); // lambda expression with return statement
(int[]) -> { multiple statments; return index; } // it can have multiple statements
In these sample examples, we have variety of lambda expression such as zero argument and single statement, multiple arguments, lambda with return statement, etc. although return statment is optional and it can have multiple statements as well.
One more thing, type of argument is optional it means if we don't provide it then compiler automaticaly interfers the type of arguments which is called type inference.
Now let's create some interesting examples to understand the use of lambda function.
Scenario Before Java 8
Suppose we have an interface that contains a single abstract method and if we provide an implementation of it using prior Java 8 then we have to use an anonymous class concept and the code looks too messy. See the following example that uses anonymous classes
interface Runnable{
public void run();
}
public class Demo {
public static void main(String[] args) {
int speed=100;
// old approach to implement
Runnable r=new Runnable(){
public void run(){System.out.println("Running at the speed of "+speed);}
};
r.run();
}
}
Example: Scenario Java 8 and Later
From Java 8 and later, we can implement such abstract methods using a lambda expression. This is the strength of lambda expression, notice it does not have any name that's why it is also known as an anonymous function.
interface Runnable{
public void run();
}
public class Demo {
public static void main(String[] args) {
int speed=100;
// new approach (lambda expression) to implement
Runnable r=()->{
System.out.println("Running at the speed of "+speed);
};
r.run();
}
}
Running at the speed of 100
Example: Lambda Expression With Parameter
Lambda Expression can have zero, one, or multiple parameters as we do with methods. Type of parameter is inferred by the lambda so it is optional, we may or may not mention parameter. See the example wherein second lambda expression we mentioned type of parameter.
interface Runnable{
public void run(int speed);
}
public class Demo {
public static void main(String[] args) {
int speed=100;
// lambda expression:
Runnable r=(carSpeed)->{
System.out.println("Running at the speed of "+carSpeed);
};
r.run(speed);
// specifying type of parameters
Runnable r1=(int carSpeed)->{
System.out.println("Running at the speed of "+carSpeed);
};
r1.run(speed);
}
}
Running at the speed of 100
Example: Lambda Expression using return Statement
The return statement is optional with a lambda expression. We may use it to return a value to the caller, in this example, we used two lambda expressions in which first does not use return statement but the second one use return statement.
interface Runnable{
public String run(int speed, int distance);
}
public class Demo {
public static void main(String[] args) {
// lambda expression: without return
Runnable r = (carSpeed,distance)->
("Distance covered "+ distance +"Km at the speed of "+carSpeed);
// calling
String r15 = r.run(80,150);
System.out.println(r15);
// lambda expression: with return statement
Runnable r1 = (int carSpeed, int distance)->{
return ("Distance covered "+ distance +"Km at the speed of "+carSpeed);
};
String fz = r1.run(100,200);
System.out.println(fz);
}
}
Distance covered 150Km at the speed of 80
Distance covered 200Km at the speed of 100
Example: Lambda Expression in Collection
Although we can use lambda expression anywhere to implement a functional interface here we are using it to iterate the collection elements. here we used the forEach() method of iterator interface.
import java.util.ArrayList;
import java.util.List;
public class Demo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.add(30);
list.add(40);
// Traversing using foreach
System.out.println("Traversing using foreach");
for(Integer element: list) {
System.out.println(element);
}
// lambda expression
System.out.println("Traversing using lambda expression");
list.forEach(element->System.out.println(element));
}
}
Traversing using foreach
10
20
30
40
Traversing using lambda expression
10
20
30
40
Example: Thread Implementation using Lambda
The Java Runnable interface is a functional interface that contains a single abstract method. We can implement its run() method using the lambda expression and create thread instance as we did in the below example.
public class Demo {
public static void main(String[] args) {
// Thread Implementation using anonymous class
Runnable run = new Runnable() {
public void run() {
System.out.println("Thread running...");
}
};
new Thread(run).start();
// Thread Implementation using lambda expression
Runnable run1 = ()->System.out.println("Thread Running using lambda...");
new Thread(run1).start();
}
}
Thread running...
Thread Running using lambda...