compose是Function接口的默认方法,用于函数复合,先执行参数函数再执行当前函数,对应数学中的f(g(x)),适合“先预处理、再主转换”场景。

compose 是 Function<T, R> 接口的默认方法,用于把两个函数串起来,先执行参数函数,再执行当前函数。它对应数学中的复合函数 f(g(x)),语义清晰,适合“先预处理、再主转换”的场景。
compose 的基本用法
compose 方法签名是:
default <V> Function<V, R> compose(Function<? super V, ? extends T> before)
它的意思是:
-
before是一个把V变成T的函数; - 当前函数是把
T变成R的函数; - 组合后的新函数,就是把
V直接变成R的函数。
简单说:输入先过 before,再进当前函数。
立即学习“Java免费学习笔记(深入)”;
常见写法示例:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
Function<String, Integer> strToInt = s -> Integer.parseInt(s);
Function<Integer, String> intToHex = i -> Integer.toHexString(i);
// 先转整数,再转十六进制字符串
Function<String, String> strToHex = intToHex.compose(strToInt);
System.out.println(strToHex.apply("255")); // 输出 "ff"这个组合等价于:intToHex.apply(strToInt.apply("255"))。
使用 compose 的关键注意事项
-
类型必须匹配:
before的输出类型(? extends T)要能赋值给当前函数的输入类型(T),否则编译不通过; -
null 安全需自行保障:
compose内部会调用Objects.requireNonNull(before),但不会检查输入值是否为 null,业务中建议提前判空或用Optional包装; -
不能混用不同函数式接口:
compose只在Function上定义,Predicate用and/or,Consumer用andThen,别强行套用; -
避免过度嵌套:三层以上
compose链容易难读,可拆成中间变量或提取为命名函数。
compose 和 andThen 的直观对比
| 写法 | 执行顺序 | 等效表达式 | 适用阅读习惯 |
|---|---|---|---|
f.compose(g) |
先 g,再 f
|
f(g(x)) |
更贴近数学表达,适合前置转换(如解析、校验) |
f.andThen(g) |
先 f,再 g
|
g(f(x)) |
更符合从左到右的代码流,适合后置加工(如格式化、映射) |
比如处理 JSON 字符串:
Function<String, Map<String, Object>> parseJson = s -> new ObjectMapper().readValue(s, Map.class);
Function<Map<String, Object>, String> extractId = map -> (String) map.get("id");
// 先解析,再取 id → compose 更自然
Function<String, String> getIdFromJson = extractId.compose(parseJson);方法引用也能参与 compose
只要签名匹配,静态方法、实例方法、构造器引用都能直接用:
Function<String, String> trim = String::trim; Function<String, String> upper = String::toUpperCase; // 先 trim,再 upper Function<String, String> cleanAndUpper = upper.compose(trim);
注意:String::trim 返回 String,String::toUpperCase 也接受 String,类型对得上,可以直接组合。
不复杂但容易忽略。

















