A functional interface defines exactly one unimplemented, implicitly abstract method. That single method gives Java enough information to accept a lambda as the interface’s behavior, replacing a small implementation class with a concise expression. section 6.2
From implementation class to behavior
A verbose version packages the predicate in a class: `LengthGreaterThanThree implements StringPredicate` and returns `value.length() > 3` from `test`. The same intent can be supplied directly as a lambda: `StringPredicate test = value -> value.length() > 3;`. The interface describes the input and output contract; the lambda supplies the transformation. section 6.2
@FunctionalInterface
public interface StringPredicate {
boolean test(String value);
}
Inspect the minimal interface declaration that makes the lambda target type possible. section 6.2
Use functional interfaces with these practical distinctions:
- Add `@FunctionalInterface` when defining a custom interface; the annotation is optional but makes accidental second abstract methods compile-time errors. section 6.2
- Prefer Java’s `Predicate`, `Function`, `Consumer`, or `Supplier` when an existing signature matches instead of creating a custom interface. section 6.2
- Use lambdas and method references to pass behavior as data, especially when a pipeline can state the intended transformation more clearly than explicit iteration. section 6.5


