Lambda expression in Java 8
-
Last Updated: July 30, 2023
-
By: javahandson
-
Series
In this article, we will learn what is a lambda expression in java 8. We will also learn how to make use of lambda expressions with proper examples.
A lambda expression is a form of method. Lambda expression takes in parameters, executes the logic, and returns a value. A lambda expression is a method without a name.
(parameters) -> expression Only single statement so curly braces are not required
(parameters) -> { statements } We have to use curly braces with multiple statements
Before going in-depth about lambda expression we will learn what is a functional interface because only by using a functional interface we can create a lambda expression.
The functional interface is an interface with only one abstract method. An abstract method will have a declaration but no definition.
package com.javahandson; public interface CalculateInterface { int calculate(int operand1, int operand2); }
If we place more than one abstract method in an interface then it will not be treated as a functional interface.
Some predefined functional interfaces in Java APIs are Comparator, Runnable etc.
We can make use of @FunctionalInterface annotation to mark the interface as functional interface.
package com.javahandson; @FunctionalInterface public interface CalculateInterface { int calculate(int operand1, int operand2); }
If we mark the interface with @FunctionalInterface and we add more than one abstract method to that interface then we will get a compile time exception.
package com.javahandson; @FunctionalInterface public interface CalculateInterface { int calculate(int operand1, int operand2); int sum(int operand1, int operand2); } Output : Invalid '@FunctionalInterface' annotation; CalculateInterface is not a functional interface
Below is the functional interface
package com.javahandson; @FunctionalInterface public interface CalculateInterface { int calculate(int operand1, int operand2); }
We will implement this interface using lambda expression as below
package com.javahandson; public class Test { public static void main(String[] args) { CalculateInterface addition = (int operand1, int operand2) -> operand1 + operand2; int result = addition.calculate(10, 20); System.out.println("Addition is : " + result); } } Output: Addition is: 30
(int operand1, int operand2) -> operand1 + operand2
Here we have created a lambda expression which is an implementation of the calculate method. calculate method takes 2 arguments and returns an integer.
Say we are implementing the CalculateInterface using an anonymous function, then it will look something like the below
package com.javahandson; public class Test { public static void main(String[] args) { CalculateInterface calculateInterface = new CalculateInterface() { @Override public int calculate(int operand1, int operand2) { return operand1 + operand2; } }; int result = calculateInterface.calculate(10, 20); System.out.println("Addition is : " + result); } }
In the above code, there is a lot of boilerplate code that is not at all required.
We know CalculateInterface is a functional interface and it will have only one method, so naming that method is not at all required also writing the new operator doesn’t bring any value hence we will remove that as well. So after removing these 2 things, we are left with
CalculateInterface calculateInterface = (int operand1, int operand2) { return operand1 + operand2; }
As part of lambda expression syntax, we should have a -> symbol between the parameters and expression hence
CalculateInterface calculateInterface = (int operand1, int operand2) -> { return (operand1 + operand2); };
At the top we have seen if we are adding multiple abstract methods in a functional interface then we get a compile-time exception saying
Invalid ‘@FunctionalInterface’ annotation; CalculateInterface is not a functional interface
Why is it so?
The main purpose of a functional interface is to create lambdas. Take a scenario and say multiple abstract methods are allowed in a functional interface. Now whenever we try to create a lambda expression with that interface then the compiler gets confused. The compiler will not understand we are providing an implementation for which abstract method and the ambiguity issue arises. Let us check the example below
package com.javahandson; //Here we cannot use @FunctionalInterface annotation as we are using multiple abstract methods public interface CalculateInterface { int calculate(int operand1, int operand2); int addition(int operand1, int operand2); }
package com.javahandson; public class Test { public static void main(String[] args) { CalculateInterface calculateInterface = (int operand1, int operand2) -> operand1 + operand2; } } Output: Output : Exception in thread "main" java.lang.Error: Unresolved compilation problem: The target type of this expression must be a functional interface
In the above example, we have the calculate method and addition method but while creating lambda, the compiler does not recognize the implementation we provided is for which abstract method hence we can see the compilation issue.
Hence we should use only one abstract method in a functional interface. If we are having only one abstract method in an interface then we can mark it with @FunctionalInterface annotation but this is optional.
Note* It is always better to mark the functional interface with @FunctionalInterface because we will get a compile time exception as soon as we try to add any new method to that functional interface.
So this is about lambda expressions in Java 8. I hope you like the article. If you are having any questions on this topic please raise them in the comments section.