Functional
Interface and Lambda Expression
Functional
Interfaces
A
functional interface is an interface that contains only one abstract
method. It
can have one or more default or static method but abstract method
should be only one.
Runnable,
Callable, ActionListener,
Comparable
are
some of the examples of functional interfaces as it contains only one
abstract method.
Let’s
see some functional Interface implementation example:
Example
1:
public
interface SimpleInterface {
public
void abstractMethod();
}
It’s
a functional Interface as it only contains a single abstract method.
Example
2:
public
interface ComplexInterface {
public
void abstractMethod();
public
default void defaultMethod(){
System.out.println(“Default
method”);
}
public
static void staticMethod(){
System.out.println(“Static
method”);
}
}
Above
example #2 is also a valid functional interface as it only contains
one abstract method and rest are either default or static method.
Example
3:
public
interface ComplexInterface {
public
void abstractMethod();
public
void anotherAbstractMethod();
public
default void defaultMethod(){
System.out.println(“Default
method”);
}
public
static void staticMethod(){
System.out.println(“Static
method”);
}
}
The
above example #3 is not a valid functional Interface as it contains
more than one abstract method.
#1
and #2 are valid Functional Interface but #3 is not. For lambda
expression, An interface must be a functional interface else you will
end up in error. So, How can we force compiler to check whether the
Interface is functional or not and if not then it should give
compiler time error?
@FunctionalInterface
Annotation
It
is used to ensure that the functional interface can’t have more
than one abstract method. If you add more or less abstract method
then compiler will show compile time error message.
Note:
An interface with one abstract method will be called as Functional
Interface whether you add the @FunctionalInterface annotation or not
but it is always a good practise to add annotation as it will avoid
addition of extra method accidentally.
Lambda
Expression
Lambda
expressions
is
used to represent the instance of a functional interface i.e. using
Functional Interface reference we are allowed to call lambda
expression implementation.
If
you don’t know what is lambda expression or how to write lambda
expression then you can read my blog on lambda expression over here.
Let’s
try to understand the above definition with few examples:
Example
4:
I
am just using the example#1 over here
public
interface SimpleInterface {
public
void abstractMethod();
}
Before
Java 8, Either we had to create anonymous inner class or we had to
implements interface to implement the function method.
class
BulkyClass implements SimpleInterface {
@Override
public
void abstractMethod(){
System.out.println(“Abstract
Method Implementation”);
}
}
To
invoke method:
class
Test {
public
static void main(String[] args){
SimpleInterface
si = new BulkyClass();
si.
AbstractMethod(); // Will display message on Console.
}
}
Now,
let’s see how Functional interface can be implemented by a Lambda
Expression.
Over
here, We don’t need any more BulkyClasses. We can just directly
call it
class
Java8 {
public
static void main(String[] args){
SimpleInterface si = () -> System.out.println(“Abstract Method Implementation”);
si.abstractMethod(); // Will display message on Console.
}
}
If
you observed it carefully, We’ve invoked the lambda expression
implementation using Functional Interface.
Let’s
see another famous Functional Interface i.e. Runnable Interface.
Runnable interface contain only one method which is run and the
return type is void
Similarly, We can write anonymous Runnable
using Lambda Expression.
public
ThreadExampleWithJava8 {
p.s.v.m()
{
Runnable
r = () -> {//stattement1
statement2;
}
Thread
th = new thread(r);
th.start();
}
}
-
As
Runnable
is a functional interface, that’s why we can use lambda expression
to create it’s instance.
-
Since
run() method takes no argument, our lambda expression also have no
argument.
-
Just
like if-else blocks, we can avoid curly braces ({}) since we have a
single statement in the method body. For multiple statements, we
would have to use curly braces like any other methods.
Why
do we need Lambda Expression
-
Reduced
Lines of Code
-
Sequential
and Parallel Execution Support
-
Passing
Behaviours
into methods
Will
explain the above point with example in my next blog. Over here,
Let’s just focus on Functional Interface and example.
Example
5:
@FunctionalInterface
public
interface firstInterface {
public
void method1();
}
@FunctionalInterface
public
interface secondInterface extends firstInterface{
}
if
an interface extends functional Inference and child interface does
not contains any abstract method then child interfaces will also be a
valid functional interface.
Example
6:
@FunctionalInterface
public
interface firstInterface {
public
void method1();
}
@FunctionalInterface
public
interface secondInterface extends firstInterface{
public
void method1();
}
If
base and super interface contains one abstract method and both method
are same then
secondInterface will also be a valid Functional Interface. Why?
Because of
Overriding property., second Interface will have only one abstract
method.
Example
7:
@FunctionalInterface
public
interface firstInterface {
public
void method1();
}
@FunctionalInterface
public
interface secondInterface extends firstInterface{
public
void method2();
}
Over
here, Second Interface will throw compile time error as it will be
having two method i.e. method2 as will as method1 from
firstInterface.
Example
8:
@FunctionalInterface
public
interface firstInterface {
public
void method1();
}
public
interface secondInterface extends firstInterface{
public
void method2();
}
Over
here, Though
Second
Interface is
not a Functional Interface still it will
not
throw any
compile time error as it
doesn’t have @FunctionalInterface annotation.