java中function接口的compose和andthen实现函数组合:compose先执行参数函数再执行当前函数,andthen则相反;二者均支持链式调用,提升代码清晰度与复用性。

Java 中 Function 接口的 compose 和 andThen 是实现函数组合的核心方法,它们让多个函数像流水线一样串起来执行,无需手动嵌套调用,代码更清晰、复用性更高。
compose:先执行参数函数,再执行当前函数
compose 的签名是:<v> Function<v r> compose(Function<v t> before)</v></v></v>。它表示“先做 before,再做当前函数”。输入类型是 V,输出类型是当前函数的返回类型 R。
比如:
Function<string integer> strToInt = s -> Integer.parseInt(s);
Function<integer string> intToHex = i -> String.format("0x%x", i);
// 先转整数,再转十六进制字符串
Function<string string> strToHex = intToHex.compose(strToInt);
System.out.println(strToHex.apply("255")); // 输出 "0x ff"
</string></integer></string>等价于:intToHex.apply(strToInt.apply("255"))。
常见用法:
- 前置预处理:如字符串 trim → parse → validate,可把 trim + parse 封装为一个
compose链 - 解耦校验逻辑:把“非空校验”作为独立
Function,用compose插入到业务函数前 - 注意:
compose的参数函数必须返回类型匹配当前函数的输入类型
andThen:先执行当前函数,再执行参数函数
andThen 的签名是:<v> Function<t v> andThen(Function<r v> after)</r></t></v>。它表示“先做当前函数,再做 after”。输入类型仍是 T,输出变成 after 的返回类型 V。
同样例子:
Function<string integer> strToInt = s -> Integer.parseInt(s);
Function<integer double> intToDouble = i -> i * 1.5;
// 先转整数,再乘以 1.5
Function<string double> strToDouble = strToInt.andThen(intToDouble);
System.out.println(strToDouble.apply("10")); // 输出 15.0
</string></integer></string>等价于:intToDouble.apply(strToInt.apply("10"))。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
典型场景:
- 后置转换:如数据库查出对象 → 转 DTO → 转 JSON 字符串,用
andThen逐层包装 - 日志或监控埋点:在核心逻辑后接一个记录耗时的
Function - 异常统一包装:主函数返回结果后,用
andThen包一层Response.ok()
组合多个函数:链式调用很自然
compose 和 andThen 返回的仍是 Function,所以支持连续调用。例如:
Function<string string> clean = s -> s.trim().toLowerCase();
Function<string integer> len = s -> s.length();
Function<integer boolean> isLong = i -> i > 5;
Function<string boolean> check = clean.andThen(len).andThen(isLong);
System.out.println(check.apply(" Hello ")); // true(trim 后是 "hello",长度 5 → false?等等,是 5 不大于 5 → false)
// 改成 > 4 就对了:isLong = i -> i > 4 → true
</string></integer></string></string>也可以混用:f.andThen(g).compose(h) 相当于 g(f(h(x))),读的时候从右往左理解执行顺序。
小技巧:
- 用变量命名体现组合意图,如
parseAndValidate、toDtoAndSerialize - 避免过长链:超过 4–5 层建议拆分成中间函数,提升可读性和可测性
- 组合时注意泛型兼容性,IDE 通常能及时提示类型不匹配
和方法引用配合更简洁
实际开发中,常把静态方法或实例方法直接作为函数使用,组合起来非常干净:
Function<string string> upper = String::toUpperCase;
Function<string integer> length = String::length;
Function<string integer> upperLen = upper.andThen(length);
System.out.println(upperLen.apply("abc")); // 3
</string></string></string>甚至可以组合构造器:
Function<string integer> toInt = Integer::new; // String → Integer(需 String 是数字格式) Function<integer string> toHex = i -> "0x" + Integer.toHexString(i); Function<string string> strToHexViaCtor = toInt.andThen(toHex); </string></integer></string>
注意:方法引用要确保参数个数、类型、抛出异常都与 Function 签名一致;否则编译失败。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










