What is Functional Interface?
If an interface contains only 1 abstract method, that is known as Functional Interface.
Alos known as SAM interface (Single Abstract Method).
@ FunctionalInterface keyword can be used at top of the interface(But its optional)
@FunctionalInterface
public interface Bird {
void canFly(String val);
}
OR
public interface Bird {
void canFly(String val);
}
- @ FunctionalInterface Annotation restrict us and throws compilation error, if we try to add more than 1 abstract method.
- In Functional Interface, only 1 abstract method is allowed, but we can have other methods like default, static method or Methods inherited from the object class.
@FunctionalInterface
public interface Bird {
void canFly(String val);
default void getHeight(){
//default method implementation
}
static void canEat(){
// my static method implementation
}
String toString(); // Object class method
}
public interface TestInterface {
String toString();
}
// No need to implement toString because
//Object class already implemented
public class TestClassImplements implements TestInterface{
}
What is Lambda Expression?
Lambda expression is a way to implement the Functional Interface.
Lambda expression is introduced because of functional interface.
Before going into further into Lambda expression, lets first see:
3 Ways to Implement the Functional Interface
@FunctionalInterface
public interface Bird {
void canFly(String val);
}
Using "implements"
public class Eagle implements Bird{
@Override
public void canFly(String val) {
System.out.println("Eagle Bird implementation");
}
}
Bird eagleObject = new Eagle();
eagleObject.canFly();
Using "anonymous Class"
public class Main {
public static void main(String[] args) {
Bird eagleObject = new Bird() {
@Override
public void canFly(String val) {
System.out.println("Eagle Bird Implementation");
}
};
eagleObject.canFly("cool");
}
}
Using "Lambda Expression"
public class Main {
public static void main(String[] args) {
Bird eagleObject = (String val) -> {
System.out.println(val);
};
eagleObject.canFly("Cool");
}
}
Types of Functional Interface
Consumer
Represent an operation, that accept a single input parameter and returns no result.
Present in package: java.util.function
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
Usage
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
Consumer<Integer> loggingObject = (Integer val) -> {
if (val > 10){
System.out.println("logging");
}
};
loggingObject.accept(11);
}
}
Supplier
Represent the supplier of the result. Accepts no Input parameter but produce a result.
Present in package: java.util.function
@FunctionalInterface
public interface Supplier<T> {
T get();
}
Usage
public class Main {
public static void main(String[] args) {
Supplier<String> isEvenNumber = () -> "this is the data I am returning";
System.out.println((isEvenNumber.get()));
}
}
Function
Represent function, that accepts one argument process it and produce a result.
Present in package: java.util.function
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
Function<Integer, String> app = (Integer num) -> {
String output = num.toString();
return output;
};
System.out.println(app.apply(64));
}
}
Predicate
Represent function, that accept one argument and return the boolean.
Present in package: java.util.function;
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
import java.util.function.Predicate;
public class Main {
public static void main(String[] args) {
Predicate<Integer> isEven = (Integer val) -> {
if (val%2 == 0)
return true;
else
return false;
};
System.out.println(isEven.test(19));
}
}
Handle use case when Functional Interface extends from other Interface
Use Case 1
Functional Interface extending Non Functional Interface
public interface LivingThing {
public void canBreathe();
}
Not Possible
Use Case 2
Interface extending Functional Interface
@FunctionalInterface
public interface LivingThing {
public void canBreathe();
}
public interface Bird extends LivingThing{
void canFly(String val);
}
Use Case 3
Functional Interface extending other Functional Interface
Not possible
@FunctionalInterface
public interface LivingThing {
public void canBreathe();
}
@FunctionalInterface
public interface Bird extends LivingThing{
void canFly(String val);
}
Possible
@FunctionalInterface
public interface LivingThing {
public boolean canBreathe();
}
@FunctionalInterface
public interface Bird extends LivingThing{
public boolean canBreathe();
}
Usage
public class Main {
public static void main(String[] args) {
Bird eagle = () -> true;
System.out.println(eagle.canBreathe());
}
}