Functional Interfaces in Java
Functional Interfaces in Java - Overview, Importance, Lambda Expressions, Defining, Predefined Lists, and Examples.
Join the DZone community and get the full member experience.
Join For FreeBeing an Object-Oriented programming language, Java cannot have independent functions as everything except for some primitive data types and methods revolves around Classes and Objects. Functions have always been a part of a class that can only be called using objects or classes.
However, with the release of Java8, a new concept called function interface as well as some other features like Lambda Expressions, Time API, Stream API, etc. were released.
But what are these functional interfaces, and how can you define them? Let’s find out!
What Is an Interface?
An interface acts as an abstraction mechanism that specifies the behaviour of a class. It is also known as a blueprint of a class containing abstract methods and static constants. An interface can contain one or more abstract methods, not the method body.
Simply put, an interface is like a contract that must be honoured by every implementing class. For example:
Interface A1
{
void method1();
String method2(String X);
}
Class A1 implements A
{
@Override
public void method1(){}
@Override
public String method2(String X) { return x; }
}
Before JDK8, interfaces could not define implementations but now default implementations can be added for interface methods. We can also define static and default methods that can be called without an object in an interface.
Basically, interfaces are used to achieve multiple inheritances and loose coupling in the code.
Now that we have a clear understanding of interfaces, let’s see what a functional interface is, and how it works.
What Is a Functional Interface?
A functional interface is also known as a Single Abstract Method (SAM) Interface as it can have no more than one abstract method.
The functional interface can have multiple static and default methods with an implementation along with an additional abstract method. To mark an interface as functional, @FunctionalInterface
annotation is used to avoid declaring extra methods mistakenly.
What makes a functional interface so popular is the ability it offers to the programmer for using Lambda expressions to instantiate interfaces without using anonymous and bulky class implementations.
Moreover, using the abstract keyword in functional interfaces is optional, as the methods that are defined inside the interface are by default abstract.
But, What Do We Mean by Lambda Expressions?
Lambda expression is an unnamed or anonymous method that does not execute on its own, rather, it is used to implement functional interface’s defined methods. It is defined as:
(parameter list) -> lambda body
double getGoldenRatioValue() {
return 1.61803;
}
Using lambda expression, it can be written as:
() -> 1.61803
As we can see, the method in the lambda function does not have any parameters, making the operator’s left side empty. While the right side defines the action, in this case, it will return the value of the Golden Ratio: 1.61803.
Before Java8, implementing interfaces or creating inner class objects was crucial, but with the introduction of Java8, all we got to do was assign lambda expressions to functional interfaces.
Functional Interfaces Examples
To create functional interfaces you can either use @FunctionalInterface
annotation or use the predefined functional interfaces by Java.
Example A
- First, we will mark
@FunctionalInterface
, and create an interface calledMyInterface
with an abstract method namedgetGoldenRationValue()
. - Then we will create a public class called
main
to execute the method. - To use the lambda expression in the functional interface, we will declare a reference to
MyInterfaceDemo
and then assign the lambda expression to the reference. - Finally, we will print out the value of the Golden Ratio value using the reference interface.
import java.lang.FunctionalInterface;
// Creating and Marking Functional Interface
@FunctionalInterface
interface MyInterface {
// This is the abstract method
double getGoldenRatioValue();
}
public class Main {
public static void main( String[] args ) {
//declaring reference to the functional interface
MyInterface ref;
//using Lambda Expression
ref = () -> 1.61803;
System.out.println("Value of Golden Ratio = " + ref.getGoldenRatioValue());
}
}
Value of Golden Ratio = 1.61803
Example B
- In this example, we are going to use a predefined functional interface
ToDoubleFunction
that takes an argument T and returns a double as an output. - The
ToDoubleFuntion
contains an abstract method namedapplyasDouble()
. - Finally, we will print the message length including spaces.
import java.util.function.ToDoubleFunction;
public class MyInterface2 {
public static void main(String[] args) {
ToDoubleFunction<String> length = x -> x.length();
System.out.println(length.applyAsDouble("This is an example of predefined functional interface."));
}
}
54.0
List of Predefined Functional Interfaces
Now that we know how to define functional interfaces, let’s see how many functional interfaces are predefined.
There are four main types of functional interfaces that one can implement in different situations: Consumer, Predicate, Function, and Supplier. Among these four interfaces, Consumer, Function, and Predicate have additional functional interfaces.
Here is the list of all the built-in or predefined interfaces in Java.
Note: T, U, and R mentioned in the below table represent the type of the first argument, the second argument, and the result of the operation respectively.
Interface |
Type |
→ |
|
T, U → |
|
T, U → R |
|
T, T → R |
|
T, U → boolean |
|
→ boolean |
|
T → |
|
double, double → double |
|
double → |
|
double → R |
|
double → boolean |
|
boolean → |
|
double → int |
|
double → long |
|
double → double |
|
T → R |
|
int → int |
|
int → |
|
int → R |
|
int → boolean |
|
→ int |
|
int → double |
|
int → long |
|
int → int |
|
long, long → long |
|
long → |
|
long → R |
|
long → boolean |
|
→ long |
|
long → double |
|
long → int |
|
long → long |
|
T, double → |
|
T, int → |
|
T, long → |
|
T → boolean |
|
→ T |
|
T, U → double |
|
T → double |
|
T, U → int |
|
T → int |
|
T, U → long |
|
T → long |
|
T → T |
Takeaway
Some key takeaways to remember from this post are:
- An interface acts as an abstraction mechanism.
- The functional interface can have multiple static and default methods with an implementation along with an additional abstract method.
- Methods that are defined inside the functional interface are by default abstract, hence, using the abstract keyword is now optional.
- Lambda Expression is an anonymous method that does not execute on its own, rather, it is used to implement functional interface’s defined methods.
- To create functional interfaces you can either use
@FunctionalInterface
annotation or use the predefined functional interfaces by Java.
So, that was all about functional interfaces and we hope that it helped you understand the basics. Remember, we have only scratched the surface of functional interfaces and there’s much more that you can learn about each predefined functional interface available in Java.
Opinions expressed by DZone contributors are their own.
Comments