Functional Interfaces

Details about functional interfaces in Java.

What is Functional Interface in Java?

  • A functional interface is an interface that contains exactly one abstract method.

  • It plays a important role in implementing functional style programming.

  • Functional interface is usually marked with @FunctionalInterface annotation. While optional, this annotation helps the compiler verify that the interface adheres to the "single abstract method" rule.

  • Java's java.util.function package provides several built-in functional interfaces.

Sample Example

Create a custom functional interface and add sample logic in the main application to use the newly created interface

package org.example;

import lombok.extern.slf4j.Slf4j;

@FunctionalInterface
interface Calculator {
    int calculate(int a, int b);
}

@Slf4j
public class Application {
    public static void main(String[] args) {
        // Define a lambda expression for addition
        Calculator additionWithMethodReference = Integer::sum;
        Calculator additionWithLambdaExpression = (a,b) -> Integer.sum(a,b);

        // Use the custom functional interface
        log.info("Addition: {}", additionWithMethodReference.calculate(5, 3));
        log.info("Addition: {}", additionWithLambdaExpression.calculate(5, 3));
    }
}

Execute the program

Functional Interface vs Normal Interface

Here's a comparison table between Functional Interface and Normal Interface -

Aspect
Functional Interface
Normal Interface

Definition

Interfaces with a single abstract method

Interfaces with one or more abstract methods

Annotation

Often annotated with @FunctionalInterface

No specific annotation required

Number of Methods

Exactly one abstract method

One or more abstract methods

Default/Static Methods

Can have default and static methods

Can have default and static methods

Use Case

Designed for lambda expressions and method references

Used for general abstraction and polymorphism

Example

java.util.function.Predicate<T>

java.util.List, java.util.Map

Syntax with Lambda

Can be instantiated using lambda expressions

Cannot be directly instantiated using lambda expressions

Java 8 and Later

Introduced in Java 8

Existing since the initial versions of Java

Simplicity

Simplifies the creation of instances

More verbose to implement

Primary Purpose

To provide target types for lambda expressions and method references

To define a contract that classes must follow

Functional Interface Example

@FunctionalInterface
public interface MyFunctionalInterface {
    void perform();

    // default method
    default void log(String message) {
        System.out.println("Logging: " + message);
    }

    // static method
    static void print(String message) {
        System.out.println("Printing: " + message);
    }
}

public class FunctionalInterfaceExample {
    public static void main(String[] args) {
        MyFunctionalInterface funcInterface = () -> System.out.println("Performing action");
        funcInterface.perform();  // Output: Performing action
        funcInterface.log("Test Log");  // Output: Logging: Test Log
        MyFunctionalInterface.print("Test Print");  // Output: Printing: Test Print
    }
}

Normal Interface Example

public interface MyNormalInterface {
    void method1();
    void method2();

    // default method
    default void log(String message) {
        System.out.println("Logging: " + message);
    }

    // static method
    static void print(String message) {
        System.out.println("Printing: " + message);
    }
}

public class NormalInterfaceImplementation implements MyNormalInterface {
    @Override
    public void method1() {
        System.out.println("Method 1 implementation");
    }

    @Override
    public void method2() {
        System.out.println("Method 2 implementation");
    }

    public static void main(String[] args) {
        NormalInterfaceImplementation obj = new NormalInterfaceImplementation();
        obj.method1();  // Output: Method 1 implementation
        obj.method2();  // Output: Method 2 implementation
        obj.log("Test Log");  // Output: Logging: Test Log
        MyNormalInterface.print("Test Print");  // Output: Printing: Test Print
    }
}

Last updated