An Interface that contains exactly one abstract method is known as functional interface. It can have any number of default, static methods but can contain only one abstract method. It can also declare methods of object class.
Known for its versatility and wide acceptance, Java has gradually evolved to embrace modern programming paradigms. One of the major changes in recent years has been functional programming, inspired by languages such as Scala, Haskell, and Clojure. Functional architecture introduces a different approach to software development, which builds on the use of immutable functions and data structures as the first citizen This transition is facilitated by the introduction of user interfaces in Java.
A function interface in Java is an interface with only one abstract method. Whereas interfaces from traditional descriptive conventions implement classes, functional interfaces focus on behavior, and allow developers to treat tasks as objects. They form the cornerstone of Java programming features, enabling the use of lambda syntax and style.
Functional Interface is also known as Single Abstract Method Interfaces or SAM Interfaces. It is a new feature in Java, that helps to achieve functional programming approach.
The introduction of functional interfaces in Java 8 was a game changer, giving developers a more concise and transparent way of writing code. These interactions paved the way for the adoption of design strategies that work within the Java ecosystem.
Output:
Hello there
A functional interface can have methods of object class. Let's understand it through the following example.
Output:
Hello there
A functional interface can extend another interface only if it does not have any abstract method.
Output:
compile-time error
In the following example, a functional interface is extending to a non-functional interface.
Output:
Hello there Do it now
Functional interfaces shine when combined with lambda expressions and method references. Lambda expressions provide a concise syntax for defining anonymous functions, while method references allow developers to reference existing methods by name.
Using lambda expression with Predicate
By leveraging lambda expressions and method references, developers can write more expressive code that is easier to understand and maintain. These features enable a more functional style of programming in Java, promoting the use of immutable data and pure functions.
Java 8 introduced several built-in functional interfaces in the java.util.function package, each designed to support common functional programming patterns. Some of the most commonly used functional interfaces include:
Supplier: Represents a supplier of results.
Consumer: Represents an operation that accepts a single input argument and returns no result.
Predicate: Represents a predicate (boolean-valued function) of one argument.
Function: Represents a function that accepts one argument and produces a result.
UnaryOperator: Represents an operation on a single operand that produces a result of the same type as its operand.
BinaryOperator: Represents an operation upon two operands of the same type, producing a result of the same type as the operands.
These functional interfaces provide a foundation for writing functional-style code in Java. They encapsulate common patterns and enable developers to write more concise and readable code.
Java offers a number of function interfaces, and developers can even define their own function interfaces to suit their specific needs. This flexibility allows domain-specific functional interfaces to be tailored to the needs of specific applications.
By annotating the interface with @FunctionalInterface, developers indicate that it is intended to be used as a functional interface. This annotation is optional but serves as a documentation tool, making the intent of the interface clear to other developers.
We can also define own custom functional interface. Following is the list of functional interface that belongs to java.util.function package.
| Interface | Description |
|---|---|
| BiConsumer<T,U> | It represents an operation that accepts two input arguments and returns no result. |
| Consumer<T> | It represents an operation that accepts a single argument and returns no result. |
| Function<T,R> | It represents a function that accepts one argument and returns a result. |
| Predicate<T> | It represents a predicate (boolean-valued function) of one argument. |
| BiFunction<T,U,R> | It represents a function that accepts two arguments and returns a a result. |
| BinaryOperator<T> | It represents an operation upon two operands of the same data type. It returns a result of the same type as the operands. |
| BiPredicate<T,U> | It represents a predicate (boolean-valued function) of two arguments. |
| BooleanSupplier | It represents a supplier of boolean-valued results. |
| DoubleBinaryOperator | It represents an operation upon two double type operands and returns a double type value. |
| DoubleConsumer | It represents an operation that accepts a single double type argument and returns no result. |
| DoubleFunction<R> | It represents a function that accepts a double type argument and produces a result. |
| DoublePredicate | It represents a predicate (boolean-valued function) of one double type argument. |
| DoubleSupplier | It represents a supplier of double type results. |
| DoubleToIntFunction | It represents a function that accepts a double type argument and produces an int type result. |
| DoubleToLongFunction | It represents a function that accepts a double type argument and produces a long type result. |
| DoubleUnaryOperator | It represents an operation on a single double type operand that produces a double type result. |
| IntBinaryOperator | It represents an operation upon two int type operands and returns an int type result. |
| IntConsumer | It represents an operation that accepts a single integer argument and returns no result. |
| IntFunction<R> | It represents a function that accepts an integer argument and returns a result. |
| IntPredicate | It represents a predicate (boolean-valued function) of one integer argument. |
| IntSupplier | It represents a supplier of integer type. |
| IntToDoubleFunction | It represents a function that accepts an integer argument and returns a double. |
| IntToLongFunction | It represents a function that accepts an integer argument and returns a long. |
| IntUnaryOperator | It represents an operation on a single integer operand that produces an integer result. |
| LongBinaryOperator | It represents an operation upon two long type operands and returns a long type result. |
| LongConsumer | It represents an operation that accepts a single long type argument and returns no result. |
| LongFunction<R> | It represents a function that accepts a long type argument and returns a result. |
| LongPredicate | It represents a predicate (boolean-valued function) of one long type argument. |
| LongSupplier | It represents a supplier of long type results. |
| LongToDoubleFunction | It represents a function that accepts a long type argument and returns a result of double type. |
| LongToIntFunction | It represents a function that accepts a long type argument and returns an integer result. |
| LongUnaryOperator | It represents an operation on a single long type operand that returns a long type result. |
| ObjDoubleConsumer<T> | It represents an operation that accepts an object and a double argument, and returns no result. |
| ObjIntConsumer<T> | It represents an operation that accepts an object and an integer argument. It does not return result. |
| ObjLongConsumer<T> | It represents an operation that accepts an object and a long argument, it returns no result. |
| Supplier<T> | It represents a supplier of results. |
| ToDoubleBiFunction<T,U> | It represents a function that accepts two arguments and produces a double type result. |
| ToDoubleFunction<T> | It represents a function that returns a double type result. |
| ToIntBiFunction<T,U> | It represents a function that accepts two arguments and returns an integer. |
| ToIntFunction<T> | It represents a function that returns an integer. |
| ToLongBiFunction<T,U> | It represents a function that accepts two arguments and returns a result of long type. |
| ToLongFunction<T> | It represents a function that returns a result of long type. |
| UnaryOperator<T> | It represents an operation on a single operand that returnsa a result of the same type as its operand. |
Functional interfaces change the way Java developers program, enabling them to adopt programming styles in the language Provides the basis for lambda syntax and style Functional interfaces empower developers to write code that is concise, transparent, and they can be maintained.
As Java continues to evolve, programming is likely to play an increasingly important role in the future of the language. By effectively leveraging business interfaces and embracing programming principles, developers can open up new possibilities and create robust and scalable software systems.
We request you to subscribe our newsletter for upcoming updates.