163. Java Lambda 表达式 - Function 的链式组合

163. Java Lambda 表达式 - Function 的链式组合

在函数式编程中,我们常常希望把多个功能组合起来形成一个新的功能。Java 的 Function<T, R> 接口为此提供了两个非常实用的默认方法:

🧩 andThen() ------ 先执行当前函数,再执行参数函数

java 复制代码
Function<T, R> f1;
Function<R, V> f2;

Function<T, V> result = f1.andThen(f2);

🧩 compose() ------ 先执行参数函数,再执行当前函数

java 复制代码
Function<T, R> f1;
Function<U, T> f2;

Function<U, R> result = f1.compose(f2);

🎯 理解两者的执行顺序

方法名 执行顺序 相当于代码
andThen() f1f2 f2(f1(x))
compose() f2f1 f1(f2(x))

它们实现的是相同的功能组合 ,只是调用方式不同,谁写在前面,谁先执行


📦 实例演示:名字处理链

假设我们有一组名字,需要做如下处理:

  1. 去掉前后空格;
  2. 全部转为大写;
  3. 添加前缀 "Hello, "。

我们可以把这几个步骤封装成函数:

java 复制代码
Function<String, String> trim = String::trim;
Function<String, String> toUpper = String::toUpperCase;
Function<String, String> addPrefix = name -> "Hello, " + name;

✅ 方式一:使用 andThen() 链接函数

java 复制代码
Function<String, String> greet = trim.andThen(toUpper).andThen(addPrefix);
System.out.println(greet.apply("  alice  ")); // 输出:Hello, ALICE

执行顺序是:

  1. trim(" alice ")"alice"
  2. toUpper("alice")"ALICE"
  3. addPrefix("ALICE")"Hello, ALICE"

✅ 方式二:使用 compose() 组合函数(写法反过来)

java 复制代码
Function<String, String> greet = addPrefix.compose(toUpper).compose(trim);
System.out.println(greet.apply("  alice  ")); // 输出:Hello, ALICE

⚠️ 虽然顺序看起来反了,其实执行顺序和 andThen() 完全一样!


🧠 小贴士:如何选用?

情况 推荐方法
自然顺序思维(从左到右) andThen()
倒推逻辑(从右到左) compose()

🛑 类型兼容性注意

不论你是使用 andThen() 还是 compose(),都要确保类型兼容:

  • f1.andThen(f2)f1 的返回类型必须是 f2 的输入类型。
  • f1.compose(f2)f2 的返回类型必须是 f1 的输入类型。
java 复制代码
Function<Integer, Double> half = i -> i / 2.0;
Function<Double, String> asString = d -> "Result: " + d;

// 合法组合
Function<Integer, String> composed = half.andThen(asString);

🧪 练习题(课堂互动)

编写一个函数组合链,接收一个字符串,输出结果如下格式:

"Length: <长度>"

提示步骤:

  1. 去掉空格;
  2. 获取长度;
  3. 拼接前缀字符串。
相关推荐
C澒1 小时前
多场景多角色前端架构方案:基于页面协议化与模块标准化的通用能力沉淀
前端·架构·系统架构·前端框架
崔庆才丨静觅1 小时前
稳定好用的 ADSL 拨号代理,就这家了!
前端
江湖有缘1 小时前
Docker部署music-tag-web音乐标签编辑器
前端·docker·编辑器
Victor3561 小时前
MongoDB(2)MongoDB与传统关系型数据库的主要区别是什么?
后端
JaguarJack1 小时前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端·php·服务端
BingoGo1 小时前
PHP 应用遭遇 DDoS 攻击时会发生什么 从入门到进阶的防护指南
后端
Victor3561 小时前
MongoDB(3)什么是文档(Document)?
后端
恋猫de小郭2 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
牛奔3 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
想用offer打牌8 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp