ReviseAlgo Logo

Abstraction

Functional Interfaces

Master Single Abstract Method (SAM) contracts, @FunctionalInterface validation, and lambda integrations.

Interview: Highly tested: SAM rules, @FunctionalInterface compile checks, and integration with Java built-in function types.

Last Updated: June 13, 2026 10 min read

A Functional Interface is an interface that declares exactly one abstract method (Single Abstract Method or SAM contract). They serve as the target types for lambda expressions, method references, and constructor references.

SAM Contract

Must contain exactly one abstract method. Can contain any number of default or static methods without violating functional requirements.

Validation

The optional @FunctionalInterface annotation instructs the compiler to verify that the interface meets the single abstract method constraint.

Standard Utilities

Java provides built-in functional interfaces (e.g. Predicate, Function, Consumer) in the java.util.function package.

Single Abstract Method (SAM) Specification

An interface is functional if it specifies exactly one abstract method. However:

  • It can declare multiple default or static methods. These contain implementation bodies and do not count against the single abstract method limit.
  • If an interface declares an abstract method that overrides one of the public methods of java.lang.Object (e.g., @Override public boolean equals(Object obj);), it does not count toward the SAM limit, as every class inherits an implementation from Object.

Standard Java built-in Types

The java.util.function package provides standard functional interfaces to support lambda pipelines:

Interface Method Signature Purpose
Predicate<T> boolean test(T t) Evaluates an input against a condition, returning a boolean.
Function<T, R> R apply(T t) Transforms an input of type T into an output of type R.
Consumer<T> void accept(T t) Performs an action on an input, returning no result (void).
Supplier<T> T get() Produces or supplies a value of type T, taking no arguments.

Common Pitfalls

  • Adding methods to Functional Interfaces: Adding a second abstract method to an interface annotated with @FunctionalInterface, resulting in compilation failures.
  • Overusing Custom Functional Interfaces: Declaring new custom functional types instead of using standard built-in interfaces (like BiFunction or UnaryOperator), increasing API complexity.

Best Practices

  • Always Annotate: Apply the @FunctionalInterface annotation to make your design intent clear and prevent accidental method additions.
  • Reuse Built-In Functional Interfaces: Always look at the java.util.function package first before defining custom functional contracts.

Interview-Relevant Information

Q1: What is a Functional Interface? Can it have more than one method?
Answer: A functional interface is an interface with exactly one abstract method. It can have multiple static and default methods, as well as overridden Object class methods (like equals), without losing its functional status.

Q2: Why do we use the @FunctionalInterface annotation? Is it mandatory?
Answer: It is not mandatory; any interface with a single abstract method is functional by default. However, annotating it instructs the compiler to verify the single abstract method contract, preventing compile-time breaks if another developer adds abstract methods later.

Quick Checklist

Can you define a functional interface, explain which methods do not count against the SAM limit, and name four built-in functional interfaces and their signatures? If yes, you understand functional interfaces.

Use Cases

Defining target callbacks in stream pipelines (e.g. mapping, filtering, or reducing data elements).

Creating dynamic operation strategies (e.g. passing custom formatting calculations to log engines).

Common Mistakes

Declaring multiple abstract methods in functional interfaces, which disables lambda assignment.

Omitting the @FunctionalInterface annotation, leaving the interface vulnerable to accidental signature modifications.