Home » Functional Interface in Java

Functional Interface in Java

Functional Interface in Java

Introduction

In Java, interfaces act as blueprints that define the behavior of an object. They specify the methods an object must implement, but they don’t provide the actual implementation of those methods.

Functional interfaces are interfaces that declare exactly one abstract method. This single method defines the functionality that can be implemented by a lambda expression or an anonymous class.

Functional Interface in Java enables users to implement functional programming in Java. In functional programming, the function is an independent entity.

Therefore, Java is an object-oriented programming language i.e everything in java rotates around the java classes and their objects.

No function is independently present on its own in java. They are part of classes or interfaces. And to use them we require either the class or the object of the respective class to call that function.

The function can do anything a variable is capable to perform like passing a function as a parameter, a function returned by another function, etc. Functions in Python is an example of functional programming.

Functional interfaces were introduced in Java 8. A functional interface can contain only one abstract method and it can contain any number of static and default (non-abstract) methods.

Abstract methods are methods that do not require implementation during their declaration and must be overridden by the class implementing the interface.

Default methods can be directly used in a class implementing the interface as well as can be overridden and redefined. Static methods are required to be called using the name of the interface preceding the method name. These cannot be overridden by the classes implementing the interface.

Functional Interface in Java is also called Single Abstract Method (SAM) interface. From Java 8 onwards, to represent the instance of functional interfaces, lambda expressions are used.

A functional interface is an interface that contains only one abstract method. It can have any number of default methods, static methods, and abstract methods from the Object class. Functional interfaces are used primarily to enable functional programming techniques in Java, particularly with lambda expressions and method references.

Syntax

@FunctionalInterface
public interface MyFunctionalInterface {
    // Abstract method
    void myMethod();

    // Default methods (optional)
    default void defaultMethod() {
        // method implementation
    }

    // Static methods (optional)
    static void staticMethod() {
        // method implementation
    }

    // Abstract methods from Object class (not counted toward functional interface method count)
    boolean equals(Object obj);
    int hashCode();
    String toString();
}
Java

@FunctionalInterface Annotation

@FunctionalInterface annotation is used to ensure that the functional interface can’t have more than one abstract method. In case more than one abstract methods are present, the compiler flags an ‘Unexpected @FunctionalInterface annotation’ message. However, it is not mandatory to use this annotation.

Example



@FunctionalInterface

interface Square {
	int calculate(int x);
}

class Test {
	public static void main(String args[])
	{
		int a = 5;

		// lambda expression to define the calculate method
		Square s = (int x) -> x * x;

		// parameter passed and return type must be
		// same as defined in the prototype
		int ans = s.calculate(a);
		System.out.println(ans);
	}
}
Java

Output

25 
Java

Some Built-in Functional interface in Java

There are many interfaces that are converted into functional interfaces. All these interfaces are annotated with @FunctionalInterface. These interfaces are as follows –

  • Runnable –> This interface only contains the run() method.
  • Comparable –> This interface only contains the compareTo() method.
  • ActionListener –> This interface only contains the actionPerformed() method.
  • Callable –> This interface only contains the call() method.

In Java four main kinds of functional interfaces which can be applied in multiple situations as mentioned below:

  1. Consumer
  2. Predicate
  3. Function
  4. Supplier

1. Consumer

In Java, the Consumer functional interface is a part of the java.util.function package introduced in Java 8. It represents an operation that accepts a single input argument and returns no result. It is meant to be used in scenarios where you need to consume (or accept) some input but don’t need to produce any output.

The Consumer interface defines a single method named accept() which takes an argument of a specified type and performs some operation on it.

Syntax

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}
Java

Example

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample {
    public static void main(String[] args) {
        // Creating a list of integers
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        numbers.add(4);
        numbers.add(5);

        // Using a Consumer to perform an operation on each element of the list
        Consumer<Integer> consumer = (Integer num) -> {
            System.out.println("Processing number: " + num);
            // Perform any operation here
        };

        // Applying the consumer to each element of the list
        numbers.forEach(consumer);
    }
}
Java

Output

Processing number: 1
Processing number: 2
Processing number: 3
Processing number: 4
Processing number: 5
Java

2. Predicate

In Java, the Predicate functional interface is a part of the java.util.function package introduced in Java 8. It represents a predicate (boolean-valued function) of one argument. It is often used when you need to evaluate a condition on an object and return a boolean value indicating whether the condition is true or false.

The Predicate interface defines a single method named test() which takes an argument of a specified type and returns a boolean result.

Syntax

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}
Java

Example

import java.util.function.Predicate;

public class PredicateExample {
    public static void main(String[] args) {
        // Creating a Predicate to check if a given number is even
        Predicate<Integer> isEven = num -> num % 2 == 0;

        // Testing the Predicate with some numbers
        System.out.println("Is 5 even? " + isEven.test(5));   // false
        System.out.println("Is 10 even? " + isEven.test(10)); // true
    }
}
Java

Output

Is 5 even? false
Is 10 even? true
Java

3. Function

In Java, the Function interface is a functional interface introduced in Java 8 as part of the java.util.function package. It represents a function that accepts one argument and produces a result. This interface typically transforms the input value into an output value.

The Function interface has one abstract method called apply, which takes an argument of a certain type and returns a result of another type.

Syntax

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}
Java

Example

import java.util.function.Function;

public class FunctionExample {
    public static void main(String[] args) {
        // Example 1: Convert String to Integer
        Function<String, Integer> stringToInteger = s -> Integer.parseInt(s);
        Integer intValue = stringToInteger.apply("123");
        System.out.println("Converted Integer: " + intValue);

        // Example 2: Convert Integer to String
        Function<Integer, String> integerToString = i -> String.valueOf(i);
        String stringValue = integerToString.apply(456);
        System.out.println("Converted String: " + stringValue);

        // Example 3: Composing functions
        Function<String, Integer> stringLength = s -> s.length();
        Function<Integer, String> addPrefix = i -> "Length is: " + i;

        // Compose functions stringToInteger and addPrefix
        Function<String, String> composedFunction = stringToInteger.andThen(addPrefix);
        String result = composedFunction.apply("Hello");
        System.out.println("Result after composing functions: " + result);
    }
}
Java

Output

Converted Integer: 123
Converted String: 456
Result after composing functions: Length is: 5
Java

4. Supplier

In Java, the Supplier functional interface is part of the java.util.function package introduced in Java 8. It represents a supplier of results. It doesn’t take any argument but produces a result of a given type.

The Supplier interface has one abstract method called get, which doesn’t take any arguments but returns a result of the specified type.

Syntax

@FunctionalInterface
public interface Supplier<T> {
    T get();
}
Java

Example

import java.util.function.Supplier;

public class SupplierExample {
    public static void main(String[] args) {
        // Example 1: Supplier for generating random numbers
        Supplier<Double> randomSupplier = Math::random;
        System.out.println("Random number: " + randomSupplier.get());

        // Example 2: Supplier for generating current timestamp
        Supplier<Long> currentTimeSupplier = System::currentTimeMillis;
        System.out.println("Current timestamp: " + currentTimeSupplier.get());

        // Example 3: Supplier for providing a constant value
        Supplier<String> greetingSupplier = () -> "Hello, world!";
        System.out.println("Greeting: " + greetingSupplier.get());
    }
}
Java

Output

Random number: 0.6552812300200777
Current timestamp: 1647768122286
Greeting: Hello, world!
Java

Advantages of Functional Interface in Java:

  • Flexibility: Functional interfaces offer flexibility by allowing methods to be passed as parameters, facilitating the implementation of various behaviors without the need for multiple interfaces.
  • Conciseness: They promote concise code by enabling the use of lambda expressions, reducing verbosity and enhancing readability.
  • Parallelism: Functional interfaces can facilitate parallelism and concurrency, as they often represent operations that can be easily parallelized, such as mapping or reducing functions.
  • Composition: They support function composition, enabling the creation of complex behaviors by combining simpler functions, leading to more modular and maintainable code.
  • Functional Programming Paradigm: They align with the principles of functional programming, promoting immutability, referential transparency, and other beneficial characteristics.

Disadvantages of Functional Interface in Java:

  • Learning Curve: For developers unfamiliar with functional programming concepts, understanding and utilizing functional interfaces effectively can pose a steep learning curve.
  • Complexity: In some cases, the use of functional interfaces and lambda expressions can introduce complexity, especially in scenarios where there is a mix of imperative and functional programming styles within the same codebase.
  • Performance Overhead: While modern JVMs optimize the performance of lambda expressions and functional interfaces, there may still be a slight performance overhead compared to traditional imperative code in certain scenarios.
  • Debugging Challenges: Debugging code involving complex functional interfaces and lambda expressions can be challenging, as it may require understanding the behavior of higher-order functions and closures.
  • Compatibility: Maintaining compatibility with older versions of Java or other programming languages that do not support functional interfaces may be a concern, particularly when integrating with legacy systems or libraries.

Conclusion

functional interfaces in Java represent a significant advancement in the language’s capabilities, enabling developers to embrace functional programming principles more effectively. They facilitate the creation of concise and expressive code through lambda expressions and method references, promoting readability and maintainability. While there may be a learning curve for those new to functional programming, the benefits of functional interfaces, including flexibility, composability, and improved parallelism, make them a valuable addition to Java’s toolkit. As Java continues to evolve, functional interfaces will remain a key feature for developers seeking to write efficient and elegant code.

Frequently Asked Questions

1. What is a functional interface in Java?

A functional interface in Java is an interface that contains only one abstract method. It serves as a blueprint for functional programming constructs and is often used in conjunction with lambda expressions or method references.

2. Why are functional interfaces important?

Functional interfaces enable the implementation of functional programming concepts in Java, such as passing behavior as arguments to methods, promoting code reusability, and facilitating the creation of more concise and expressive code.

3. Can a functional interface have multiple default methods?

Yes, a functional interface can have multiple default methods. However, it must contain only one abstract method to qualify as a functional interface.