1. The Hook (The "Byte-Sized" Intro)
In a Nutshell: A functional interface is an interface with exactly one abstract method (SAM - Single Abstract Method). Annotated with @FunctionalInterface, these interfaces enable lambda expressions and method references, bringing functional programming to Java. They're the foundation of Java 8's Streams API.
Think of a voice command: "Hey Siri, [do one thing]". A functional interface is like thatβit represents a single, focused action you can pass around and execute.
2. Conceptual Clarity (The "Simple" Tier)
π‘ The Analogy: The Single-Button Remote
A functional interface is like a remote with ONE button:
- Button (single abstract method): "Play"
- What plays?: Depends on what you pass to it (music, video, podcast)
The remote doesn't care WHAT plays, just that there's one action: play!
3. Technical Mastery (The "Deep Dive")
Formal Definition
Functional Interface rules:
- Has exactly one abstract method
- Can have default methods and static methods (they don't count)
- Use
@FunctionalInterfaceannotation (optional but recommended) - Enables lambda expressions
Built-in Functional Interfaces (java.util.function):
Predicate<T>: Test condition β booleanFunction<T,R>: Transform T β RConsumer<T>: Accept T β voidSupplier<T>: Provide β T
4. Interactive & Applied Code
// Custom functional interface
@FunctionalInterface
interface Calculator {
int calculate(int a, int b); // Single abstract method
// Default methods allowed
default void printResult(int result) {
System.out.println("Result: " + result);
}
}
public class Main {
public static void main(String[] args) {
// OLD WAY: Anonymous class
Calculator add = new Calculator() {
@Override
public int calculate(int a, int b) {
return a + b;
}
};
// NEW WAY: Lambda expression!
Calculator subtract = (a, b) -> a - b;
Calculator multiply = (a, b) -> a * b;
System.out.println(add.calculate(10, 5)); // 15
System.out.println(subtract.calculate(10, 5)); // 5
System.out.println(multiply.calculate(10, 5)); // 50
// Built-in functional interfaces
java.util.function.Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4)); // true
java.util.function.Function<String, Integer> length = s -> s.length();
System.out.println(length.apply("Hello")); // 5
}
}5. The Comparison & Decision Layer
Common Functional Interfaces
| Interface | Method | Use Case |
|---|---|---|
Predicate<T> | boolean test(T t) | Filtering/conditions |
Function<T,R> | R apply(T t) | Transformation |
Consumer<T> | void accept(T t) | Side effects |
Supplier<T> | T get() | Lazy value generation |
6. The "Interview Corner" (The Edge)
The "Killer" Interview Question:
"What makes an interface 'functional'?"
Answer: A functional interface has exactly ONE abstract method (SAM). This allows it to be represented as a lambda expression. Default/static methods don't count. Examples: Runnable, Comparable, Comparator.
Pro-Tip: Use lambdas for concise code:
// Before Java 8
list.forEach(new Consumer<String>() {
public void accept(String s) {
System.out.println(s);
}
});
// Java 8+
list.forEach(s -> System.out.println(s));
// Even shorter: method reference
list.forEach(System.out::println);