Java 56: Functional Composition — andThen & compose
easy⏱ 5 mincoursejava
andThen vs compose: la dirección
f.andThen(g) produce x -> g(f(x)) — aplica f luego g (orden de lectura izquierda-a-derecha). f.compose(g) produce x -> f(g(x)) — aplica g primero (el clásico f ∘ g matemático). Son imágenes espejo; elige la que se lea natural. andThen es más común en código de pipeline porque coincide con el orden en que escribes los pasos.
Function<Integer,Integer> times2 = x -> x * 2;
Function<Integer,Integer> plus3 = x -> x + 3;
times2.andThen(plus3).apply(5); // (5*2)+3 = 13
times2.compose(plus3).apply(5); // (5+3)*2 = 16
Combinadores de Predicate
Predicate<T> compone con and, or, negate, devolviendo un nuevo predicado. isEven.and(isPositive) corto-circuita como &&; isEven.or(isBig) como ||; isEven.negate() lo invierte. Esto convierte las condiciones de filtro en bloques nombrados y testeables en vez de una lambda booleana gigante — y puedes guardar y reusar cada pieza.
Compón un pipeline de transformación
Implementa un Fn<A,B> componible con andThen y compose. Construye trim, toUpper y exclaim y encadena trim.andThen(toUpper).andThen(exclaim) sobre " hello " para obtener "HELLO!". Luego muestra que el orden importa: times2.andThen(plus3) en 5 = 13, pero times2.compose(plus3) en 5 = 16. También construye un Pred<T> con and/or/negate y filtra [1..8] por isEven.and(x => x > 3) para obtener [4,6,8].
Nombra tus funciones
La composición rinde más cuando cada paso tiene un nombre. parseDate.andThen(toUtc).andThen(format) documenta la intención mucho mejor que una lambda inline haciendo las tres. Los campos Function/Predicate guardados también se vuelven testeables en aislamiento — una gran ganancia de mantenibilidad frente a lambdas inline gigantes.
Quiz: f.compose(g).apply(x)
Dados f = x->x*2 y g = x->x+3, ¿cuánto es f.compose(g).apply(5)? 16 — compose corre g primero: g(5)=8, luego f(8)=16. (andThen daría (5*2)+3 = 13.) Recuerda: compose = interno primero (matemático), andThen = izquierda a derecha.