Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Functional Interfaces in Java 8

Overview

Functional interfaces are a new feature introduced in Java 8. They are interfaces that have a single abstract method, and can thus be implemented using lambda expressions, method references, or anonymous classes. This makes them a key component of the functional programming paradigm in Java.

Definition

A functional interface is defined with the help of the @FunctionalInterface annotation, although this annotation is optional. The presence of a single abstract method is what makes an interface functional.

Example: Defining a Functional Interface

@FunctionalInterface
interface MyFunctionalInterface {
    void myMethod();
}

Built-in Functional Interfaces

Java 8 provides several built-in functional interfaces in the java.util.function package. Some of the most commonly used ones are:

  • Predicate<T>: Represents a predicate (boolean-valued function) of one argument.
  • Function<T, R>: Represents a function that accepts one argument and produces a result.
  • Supplier<T>: Represents a supplier of results.
  • Consumer<T>: Represents an operation that accepts a single input argument and returns no result.
  • UnaryOperator<T>: Represents an operation on a single operand that produces a result of the same type as its operand.
  • BinaryOperator<T>: Represents an operation upon two operands of the same type, producing a result of the same type as the operands.

Example: Using a Built-in Functional Interface

Using Predicate to filter a list of strings:

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PredicateExample {
    public static void main(String[] args) {
        List names = Arrays.asList("Alice", "Bob", "Charlie", "David");
        Predicate startsWithA = name -> name.startsWith("A");
        
        List namesStartingWithA = names.stream()
                                               .filter(startsWithA)
                                               .collect(Collectors.toList());
        
        System.out.println(namesStartingWithA);
    }
}

Lambda Expressions with Functional Interfaces

Lambda expressions are a natural fit for functional interfaces. They allow you to provide the implementation of the abstract method defined by the functional interface.

Example: Implementing a Functional Interface using a Lambda Expression

@FunctionalInterface
interface MyFunctionalInterface {
    void myMethod();
}

public class LambdaExample {
    public static void main(String[] args) {
        MyFunctionalInterface myFunc = () -> System.out.println("Hello, World!");
        myFunc.myMethod();
    }
}

Method References with Functional Interfaces

Method references can also be used to provide implementations for functional interfaces, making the code even more concise and readable.

Example: Implementing a Functional Interface using a Method Reference

import java.util.function.Consumer;

public class MethodReferenceExample {
    public static void main(String[] args) {
        Consumer printer = System.out::println;
        printer.accept("Hello, Method Reference!");
    }
}

Custom Functional Interfaces

In addition to the built-in functional interfaces, you can create your own custom functional interfaces to meet specific needs in your application.

Example: Creating and Using a Custom Functional Interface

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

public class CustomFunctionalInterfaceExample {
    public static void main(String[] args) {
        Calculator add = (a, b) -> a + b;
        Calculator subtract = (a, b) -> a - b;
        
        System.out.println("Addition: " + add.calculate(5, 3));
        System.out.println("Subtraction: " + subtract.calculate(5, 3));
    }
}

Conclusion

Functional interfaces in Java 8 are a powerful feature that enable functional programming paradigms. By using built-in and custom functional interfaces along with lambda expressions and method references, you can write more concise and readable code.