A lambda is an instance of a functional interface — an interface with a single
abstract method. The java.util.function package gives you the vocabulary to
express most behaviors without defining your own.
The four you use most
Function, Supplier, Consumer, and Predicate cover transform, produce,
consume, and test. Compose them to build pipelines.
Function<String, String> trim = String::strip;
Function<String, String> upper = String::toUpperCase;
Function<String, String> clean = trim.andThen(upper);
Predicate<String> nonEmpty = s -> !s.isBlank();Accept behavior as a parameter
Passing a lambda lets a method defer a decision to the caller.
<T> T retry(Supplier<T> action, int attempts) {
for (int i = 0; i < attempts - 1; i++) {
try { return action.get(); } catch (Exception ignored) {}
}
return action.get();
}Takeaways
- Prefer method references (
String::strip) when they read more clearly. - Compose with
andThen,compose,and, andor. - Keep lambdas short; extract a named method when logic grows.
If you need to throw checked exceptions from a lambda, define a custom functional interface — the built-in ones do not declare them.