Functional Interface in Java
A functional interface in java has only one abstract method, and it can have any number of default and static methods. It makes it easier to write lambda expressions.
The Displayable user-defined interface has one and only one abstract method, so it is a functional interface.
@FunctionalInterface public interface Displayable { public abstract void display(); }
Code with an anonymous inner class
Before Java 8, we have to create an object of an anonymous inner class, i.e., Runnable. Also, to provide the implementation of the run() method, we have to write some boilerplate code.
public class Demo { public static void main(String[] args) { // creating instance of anonymous // inner class Thread t = new Thread(new Runnable() { @Override public void run() { System.out.println("Your runnable task here."); } }); t.start(); } }
Code with a functional interface and lambda expression
We saw that the boilerplate code is a problem, and to fix it, we can rewrite the code as below.
// Program to demonstrate // lambda expression public class Demo { public static void main(String[] args) { Thread t = new Thread(() -> { System.out.println("Your runnable task here."); }); t.start(); } }
In the above example, we passed Runnable using a lambda expression.
It became a lot easier to pass a function as a parameter to methods or constructors.
Valid and Invalid examples:
Let’s have a look at some examples of valid and invalid functional interfaces.
Valid example:
@FunctionalInterface public interface Foo { abstract void doWork(); }
Invalid example:
public interface Foo { abstract void doWork(); abstract void print(); }
The above example is invalid, as it has two abstract methods.
If we annotate the above interface with @FunctionalInterface, It will raise compiler error.
Writing Functional Interface in Java
@FunctionalInterface public interface MathOperation { abstract int compute(int a, int b); }
Using MathOperation to implement sum and multiply behavior.
public class MathOperationDriver { public static void main(String[] args) { MathOperation sum = (int a, int b) -> a + b; System.out.println("Sum is " + sum.compute(2, 3)); MathOperation multiply = (int x, int y) -> x * y; System.out.println("Multiplication is " + multiply.compute(10, 5)); } }
Output:
Sum is 5 Multiplication is 50
Java built-in functional interfaces
java.util.function package provides a set of built-in interfaces to solve the most common problems.
Predicate
boolean test(T t);
The below example shows how to test for odd and even numbers with Predicate.
PredicateisOdd = (a) -> a % 2 == 1; System.out.println(isOdd.test(5)); Predicate isEven = (b) -> b % 2 == 0; System.out.println(isEven.test(6));
Consumer
It is used to consume value and does not return anything. It operates without any side effects.
void accept(T t);
It accepts the value, performs the operation, and returns nothing.
ConsumerprintValue = (x) -> System.out.println("Value is " + x); printValue.accept(6);
Supplier
It does not take any argument but returns a value. It doesn’t specify that the distinct result must be returned each time.
T get();
Suppliersupplier = () -> Math.random() * 100; System.out.println(supplier.get());
Summary
- Functional Interface is introduced in Java 8.
- It can have one abstract method and multiple default methods.
- It became easier to provide the functionality of the interface using a lambda expression.
- Java has built-in interfaces in java.util.function package.
If you like the article, please share it.