Function接口通过andThen(正向串行)和compose(反向嵌套)实现类型安全的函数组合,支持声明式数据处理链,但需主动处理null以保障健壮性。

Function 接口是 Java 8 函数式编程中实现“单输入→单输出”转换的核心工具,组合多个转换函数的关键在于 andThen 和 compose 两个默认方法——它们不改变原始函数,而是返回新的组合函数,真正实现逻辑复用与声明式表达。
用 andThen 串行执行:先当前,再后续
andThen 表示“做完我,再做你”,适合按自然处理顺序拼接步骤。比如把字符串转小写 → 去首尾空格 → 取长度:
- Function
toLower = String::toLowerCase; - Function
trim = String::trim; - Function
length = String::length; - Function
pipeline = toLower.andThen(trim).andThen(length); - int result = pipeline.apply(" HELLO "); // 得到 5
注意:andThen 的类型推导依赖前后函数的输入/输出匹配,中间若类型断层(如 String → Integer 后接 Integer → Boolean),编译器会直接报错,这是类型安全的优势。
用 compose 反向组装:先前置,再当前
compose 更贴近“我要对什么数据做这件事”的思维,语义上等价于数学中的 f(g(x))。例如想先解析字符串为整数,再乘以 2:
立即学习“Java免费学习笔记(深入)”;
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- Function
parseInt = Integer::parseInt; - Function
timesTwo = x -> x * 2; - Function
parseAndDouble = timesTwo.compose(parseInt); - int n = parseAndDouble.apply("42"); // 得到 84
对比 andThen:timesTwo.andThen(parseInt) 是非法的(Integer → Integer 后接 Integer → Integer?类型没错但逻辑错——parseInt 不接受 Integer),而 compose 能让前置转换更清晰。
嵌套组合与实际业务链构建
真实场景常需多层加工,比如用户对象 → 提取邮箱 → 小写化 → 截取域名 → 去掉后缀:
- Function
getEmail = User::getEmail; - Function
toDomain = email -> email.substring(email.indexOf('@') + 1); - Function
removeTld = domain -> domain.split("\.")[0]; - Function
extractCleanDomain = getEmail.andThen(String::toLowerCase).andThen(toDomain).andThen(removeTld); - // 可直接用于 Stream.map(extractCleanDomain)
这种写法避免了临时变量、显式循环和重复 null 检查;若某步可能为空,可在对应 Function 内统一加 Objects.requireNonNull 或 Optional 处理,保持链干净。
搭配 identity 与空值防护提升健壮性
identity() 是恒等函数,常用于占位或条件组合;而空值问题需主动防御,不能依赖 andThen 自动跳过:
- // 安全提取 name,空则返回空字符串
- Function
safeName = u -> u == null ? "" : u.getName(); - // 组合时仍可参与,不会中断整个链
- Function
nameLength = safeName.andThen(String::length);
不要指望 Function 自动处理 null —— apply 方法本身不抛 NPE 就是陷阱,务必在源头或关键节点做判空。

















