Practical guide to Functional Interface and Lambda Expression in Java
Before getting started, let’s recap
What is Interface?
Interface is the way to achieve full Abstraction, it form a contract between implementing classes and outside users. It contains set of public abstract methods which is enforced to implement by inheriting classes.
Functional Interface
The next question is, “What is Functional Interface?”.
In simple words, Interface having only one abstract method is Functional Interface. But, multiple default and static methods can be found in the same interface.
Above “Animal” interface have 4 abstracts methods. To make it Functional Interface we will remove 3 methods.
Now, this is usable Functional Interface. There is @FunctionalInterface annotation (defined inside java.lang) available to enforce this behavior.
Notice the error in below code.
The error “Multiple non-overriding abstract methods found”.
@FunctionalInterface will make sure that there is only one abstract method present in interface.
We have created “Animal” Functional Interface, now let’s explore different ways to create instances like “Horse” and “Cat” from it.
1. Conventional Way
Conventionally we need to create “Horse” and “Cat” implementing “Animal” interface and Override the abstract method.
Horse Class:
Cat Class:
Now, let’s create instances of the classes.
2. Anonymous Class
A class that doesn’t have any name is called Anonymous Class. Anonymous classes usually used where the requirement is to create single object extending subclasses or implementing interfaces.
In the above code, we are not creating other classes like Conventional way.
3. Lambda Expression
Lambda expressions are instances of functional interface. It was introduced in Java 8 and it was Java’s first step into functional programming.
Lambda expressions defines the implementation of abstract method of Functional Interface.
Let’s see how can we write our above logic using lambda expression.
Just focus on the method we have overridden above, it is taking language as input and performing given logic. It’s that simple.
Syntax of Lambda Expression:
Input Arguments: Think of the arguments we have provided in the interface, it should be same.
For 0 arguments:
() -> System.out.println("I have no args");
For multiple arguments:
(a, b, c) -> a+b+c;
Arrow: The ->
symbol separate input from body.
Body: It contains code logic. It can be a single expression or a block of code enclosed in {}
. Remember, if there are multiple lines of code enclosed in {}
then “return” statement is required if the return type is not void in abstract method signature of Functional Interface.
(a, b, c) -> {
int sum = a+b;
return sum+c;
};
We have seen how elegant Lambda Expression is. But, there is additional overhead of creating Functional Interfaces, isn’t it?
Well, java.util.function comes here as a saviour.
It contains many Functional Interfaces suitable for common use-case scenarios. Let’s check few of them.
Consumer: It takes single argument and return nothing.
BiConsumer: It takes two arguments and return nothing.
Function: It takes two arguments <T, R>. T as input and return R.
BiFunction: It takes three arguments <T, U, R>. T and U as input and return R.
Supplier: It takes 0 input and return 1 output.
Predicate: It takes 1 input and return boolean.
Conclusion
Lambda Expressions makes Java aligned with modern Functional Programming trends, also it makes code more readable. Hope you find this article interesting and practical. I wish you feel more comfortable implementing it from now. I will come up with Stream API article soon where you will find significance of Lambda. Till then, Happy Learning and Happy Coding!