andThen 与 compose 是 Java 函数式串联核心方法:andThen(f, g) 表示先 f 后 g(g(f(x))),适合线性流程;compose(f, g) 表示先 g 后 f(f(g(x))),适合前置加工;二者类型需严格匹配,且需规避空值与副作用。

Java 中通过 andThen 和 compose 串联函数,核心是让数据按确定顺序流经多个单职责转换步骤,而不是写嵌套调用或临时变量。关键在于理解二者方向相反、适用场景不同,选对方法才能让逻辑清晰可读。
andThen:先执行当前函数,再交给下一个处理
调用 f.andThen(g) 得到的新函数,等价于 g(f(x))。适合“先做 A,再基于结果做 B”的线性流程,比如解析 → 格式化 → 加密。
- 参数类型要对得上:f 输出类型必须和 g 输入类型一致
- 返回的是新
Function<T, V>,原函数不变,符合函数式不可变原则 - 常见用法:把校验、转换、日志等通用逻辑封装成独立 Function,再用 andThen 拼接
compose:先执行传入函数,再交给当前函数处理
调用 f.compose(g) 得到的新函数,等价于 f(g(x))。适合“先准备输入,再交给主逻辑”的前置加工场景,比如字符串清洗 → 转数字 → 计算。
- g 的输出类型必须匹配 f 的输入类型
- 语义上更贴近数学复合函数写法(f∘g),但 Java 里不如 andThen 直观常用
- 当主逻辑(f)固定,而上游数据源多样时,用 compose 封装不同预处理更灵活
组合时必须注意的三个细节
串联不是简单拼接,容易出错的地方集中在类型、空值和副作用上:
立即学习“Java免费学习笔记(深入)”;
- 类型链必须严格连续:每个环节的输出类型 = 下个环节的输入类型,编译器会检查,但泛型擦除后运行时报错难定位
- 空值不自动处理:如果中间某步返回 null,后续 apply 可能触发 NullPointerException,建议在关键节点加 Objects.requireNonNull 或用 Optional 包装
- 保持纯函数:避免在 lambda 里改外部状态或依赖时间/随机数,否则组合后行为不可预测
实际组装小技巧
复杂流水线不要一次性写完,推荐分阶段构建并命名中间函数:
- 先定义原子函数,如
parseJson、enrichWithUser、maskPhone - 用 andThen 从左到右组装主路径:
parseJson.andThen(enrichWithUser).andThen(maskPhone) - 对分支逻辑(如空值 fallback),可配合
Optional.ofNullable(x).map(...).orElse(...)补充,不破坏函数链 - 调试时可插入日志函数:
f.andThen(x -> { System.out.println("after f: " + x); return x; }).andThen(g)


















