Functional Interfaces

In Java, a functional interface is an interface that contains only one abstract method.

It’s recommended that all functional interfaces have an informative @FunctionalInterface annotation. This clearly communicates the purpose of the interface, and also allows a compiler to generate an error if the annotated interface does not satisfy the conditions.

@FunctionalInterface
interface MyFunctionalInterface {
    void myMethod(); // Abstract method
    // Other methods (default or static) are allowed as long as there is only one abstract method.
}

Functional interfaces and streams

Functional interfaces are often used in combination with Java Streams to perform operations on collections of data in a functional and concise manner. Let's create an example where we have a list of numbers and we want to filter out the even numbers, square each remaining number, and then find their sum using streams and functional interfaces.

import java.util.Arrays;
import java.util.List;

@FunctionalInterface
interface MathOperation {
    int operate(int num);
}

public class StreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // Using functional interface and streams to filter, map, and reduce
        int result = numbers.stream()
                .filter(n -> n % 2 != 0)             // Filter out even numbers
                .map(new SquareOperation()::operate) // Square each 
                .reduce(0, Integer::sum);            // Sum the squared numbers

        System.out.println("Result: " + result);
    }

    // Implementation of the MathOperation functional interface for squaring 
    static class SquareOperation implements MathOperation {
        @Override
        public int operate(int num) {
            return num * num;
        }
    }
}

In this example:

  • MathOperation is a functional interface with a single abstract method operate(int num).
  • The SquareOperation class implements the MathOperation interface and provides the implementation for squaring a number.
  • In the main method, we have a list of numbers, and we use streams to filter out even numbers, map each remaining number using the SquareOperation, and then reduce (sum) the squared numbers using the reduce operation.
  • The result is printed, which is the sum of the squares of the odd numbers in the list.