Working with Functional Interfaces

1. Using Predicate<T>

MethodUse
test(T)Returns boolean
and(other)Logical AND
or(other)Logical OR
negate()Logical NOT
Predicate.isEqual(o)Equality predicate
Predicate.not(p) JAVA 11+Static negation

2. Using Function<T,R>

Example: Function composition

Function<String, Integer> len = String::length;
Function<Integer, Integer> sq = x -> x * x;
Function<String, Integer> lenSquared = len.andThen(sq);  // len → sq
Function<String, Integer> squareLen = sq.compose(len);   // len → sq
MethodUse
apply(T)Returns R
andThen(after)Apply this, then after
compose(before)Apply before, then this
identity()Returns input unchanged

3. Using Consumer<T>

MethodUse
accept(T)Side-effect, returns void
andThen(after)Chain consumers

4. Using Supplier<T>

MethodUse
get()Produces T (no input)
CommonLazy init, default value providers

5. Using UnaryOperator<T>

AspectDetail
ExtendsFunction<T,T>
UseSame input/output type (e.g., list.replaceAll)
identity()Static factory

6. Using BinaryOperator<T>

AspectDetail
ExtendsBiFunction<T,T,T>
FactoriesminBy(cmp), maxBy(cmp)
UseReductions, accumulators

7. Using BiPredicate<T,U>

MethodUse
test(T, U)Returns boolean
and/or/negateCombinators

8. Using BiFunction<T,U,R>

MethodUse
apply(T, U)Returns R
andThen(fn)Chain Function on result

9. Using BiConsumer<T,U>

MethodCommon Use
accept(T, U)Map.forEach, side-effects on pairs

10. Creating Custom Functional Interfaces

Example: Custom interface

@FunctionalInterface
interface ThrowingFunction<T, R, E extends Exception> {
    R apply(T input) throws E;
}
ThrowingFunction<String, Integer, IOException> reader =
    s -> Files.readString(Path.of(s)).length();
Use CaseDetail
Checked exceptionsStandard interfaces don't allow them
Domain-specificClearer than generic Function

11. Combining Predicates

Example: Predicate composition

Predicate<String> nonNull = Objects::nonNull;
Predicate<String> nonEmpty = s -> !s.isEmpty();
Predicate<String> valid = nonNull.and(nonEmpty);

users.stream().filter(Predicate.not(User::isBlocked)).toList();
CombinatorResult
p1.and(p2)Both true
p1.or(p2)Either true
p.negate()Inverted

12. Composing Functions

MethodOrder
f.andThen(g)g(f(x))
f.compose(g)f(g(x))