Lambdas and functional programming
A lambda is an implementation of a functional interface—an interface with one abstract method.
Common functional interfaces
Predicate<T>: T → booleanFunction<T,R>: T → RConsumer<T>: T → voidSupplier<T>: () → TUnaryOperator<T>: T → TBiFunction<T,U,R>: (T,U) → R
Primitive specializations such as IntPredicate avoid
boxing.
Syntax and capture
Predicate<Order> expensive = order -> order.total().compareTo(limit) > 0;
orders.removeIf(expensive.negate());Lambdas can capture local variables only when they are final or effectively final. Captured object state may still be mutable; this restriction does not make concurrency automatically safe.
Method references
Type::staticMethod, instance::method,
Type::instanceMethod, and Type::new can make
intent clearer when they match the target functional interface. Use a
lambda when argument flow would otherwise be mysterious.
Composition
Predicates compose with and, or, and
negate. Functions compose with compose and
andThen. Small pure functions are easy to test and
parallelize, but real systems still need controlled side effects.
Effectively final and
this
this inside a lambda refers to the enclosing object. In
an anonymous class, this refers to the anonymous instance.
Lambdas do not introduce a new this scope.
Feynman check
A functional interface is a socket with one action. A lambda is a compact plug that supplies that action. The variable's declared interface tells Java which plug shape the lambda must fit.