Java 8
Functional Interfaces
Lambda Expressions
Java Programming
Software Development

What are functional interfaces used for in Java 8?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Functional interfaces are a fundamental development in Java 8 that allows Java to embrace functional programming. Java is traditionally an object-oriented language, but with the advent of Java 8, it has started supporting functional programming paradigms, making the code concise and more readable.

What is a Functional Interface?

A functional interface in Java is an interface that contains exactly one abstract method. This is a key requirement, as it sets the foundation for implementing lambda expressions. Functional interfaces can have any number of default or static methods, but they must have only one abstract method. This single abstract method signature determines the function that the lambda expression can implement.

Key Characteristics:

  • Single Abstract Method (SAM): A functional interface must have exactly one abstract method.
  • SAM Interface: Functional interfaces are also known as SAM (Single Abstract Method) interfaces.
  • java.lang.FunctionalInterface Annotation: This annotation can be used to indicate that an interface is a functional interface. However, use of this annotation is optional; the interface will still be functional without this annotation.

Here's a simple example of a functional interface:

java
1@FunctionalInterface
2interface MyFunctionalInterface {
3    void execute();
4}

In the above example, MyFunctionalInterface is a functional interface containing one abstract method, execute().

Using Functional Interfaces with Lambda Expressions

Functional interfaces enable lambda expressions to be used, thereby supporting functional programming paradigms. Prior to Java 8, anonymous classes could be used to achieve similar functionality but were more verbose. Here's a comparison between using an anonymous class and a lambda expression:

Anonymous Class:

java
1MyFunctionalInterface myFunc = new MyFunctionalInterface() {
2    @Override
3    public void execute() {
4        System.out.println("Executing...");
5    }
6};

Lambda Expression:

java
MyFunctionalInterface myFunc = () -> System.out.println("Executing...");

The lambda expression version is concise, more readable, and conveys the intention directly.

Built-in Functional Interfaces in Java 8

Java 8 provides several built-in functional interfaces in the java.util.function package:

  • Predicate<T>: Represents a boolean-valued function with one argument.
  • Function<T, R>: Applies a function to its input and produces a result.
  • Consumer<T>: Performs an operation on a single argument.
  • Supplier<T>: Supplies a result without accepting any input.
  • UnaryOperator<T>: Represents an operation on a single operand, both input and output are of the same type.
  • BinaryOperator<T>: Takes two inputs of the same type and returns a result of the same type.

Here's an example using Predicate:

java
Predicate<Integer> isEven = num -> num % 2 == 0;
System.out.println(isEven.test(4)); // Outputs: true

Advantages of Functional Interfaces

  1. Enhanced Readability: Lambda expressions reduce boilerplate code, enhancing code readability.
  2. Encourages Declarative Style: With lambda expressions, Java 8 encourages a more functional, declarative style of programming.
  3. Improved API Utilization: Java 8 APIs can utilize functional interfaces to support operations like filtering, mapping, and reducing, facilitating easier data manipulation.
  4. Effective Multithreading: Functional interfaces can simplify multithreaded code using features like CompletableFuture.

Table: Summary of Built-in Functional Interfaces

Functional InterfaceDescriptionAbstract Method Signature
Predicate<T>Evaluates a condition/checks a property on an object.boolean test(T t)
Function<T, R>Transforms a function from T to R.R apply(T t)
Consumer<T>Performs an operation on an input.void accept(T t)
Supplier<T>Supplies an instance of T.T get()
UnaryOperator<T>Unary function, inputs and outputs are the same type.T apply(T t)
BinaryOperator<T>Binary function, two inputs and an output all same type.T apply(T t1, T t2)

Conclusion

Functional interfaces play a crucial role in Java 8 by enabling functional programming capabilities through lambda expressions. They promote a more expressive, concise, and agile way of coding, improving Java's expressiveness across various APIs especially in the context of collections, parallel processing, and asynchronous programming.

By understanding and utilizing functional interfaces, developers can not only write cleaner and more maintainable code but also leverage the full potential of Java 8's functional features.


Course illustration
Course illustration

All Rights Reserved.