bifunction是java 8引入的函数式接口,用于两个输入、一个输出的转换场景,声明为bifunction,含唯一抽象方法r apply(t t,u u),广泛用于数据合并、stream/optional链式调用及结果后处理。

BiFunction 是 Java 8 引入的函数式接口,专为“两个输入、一个输出”的转换或计算场景设计,用起来直接、类型安全,且天然适配 Stream、Optional 等现代 API。
核心写法:定义 + apply 调用
它声明为 BiFunction
- 写一个加法器:
BiFunction<integer integer> add = (a, b) -> a + b;</integer>,调用add.apply(3, 7)得到 10 - 拼接字符串:
BiFunction<string string> join = (prefix, suffix) -> prefix + "-" + suffix;</string>,join.apply("user", "123")返回 "user-123" - 构造对象:
BiFunction<string integer person> builder = Person::new;</string>,前提是 Person 有对应参数的构造器
业务中做双源数据合并转换
当需要把两个不相关的输入“揉在一起”生成新结构时,BiFunction 比写工具方法更清晰、易复用。
- 用用户 ID(String)和缓存 Map(Map
)查出并封装 VO: BiFunction<string map user>, UserVO> toVo = (id, cache) -> Optional.ofNullable(cache.get(id)).map(UserVO::fromUser).orElse(null);</string> - 把原始金额(BigDecimal)和折扣率(BigDecimal)转成实付金额:
(amt, rate) -> amt.multiply(BigDecimal.ONE.subtract(rate)) - 组合 HTTP 请求头(Map
)和请求体(OrderDTO),校验后生成上下文对象 Context
配合 Stream 和 Optional 提升表达力
它不是孤立存在的,常嵌入在链式调用中,让逻辑更紧凑。
- Stream.collect 里处理 key 冲突:
Collectors.toMap(k -> k.getId(), v -> v, (v1, v2) -> v1.merge(v2)),第三个参数就是 BiFunction - Optional 链式取值:
userId.flatMap(id -> userOpt.map(u -> fullNameBiFunc.apply(id, u))),避免层层 if 判空 - 用 andThen 做结果后处理:
BiFunction<integer integer> sumThenDouble = (a, b) -> a + b; sumThenDouble.andThen(x -> x * 2).apply(4, 6)</integer>→ 先得 10,再 ×2 得 20
实用提醒:别踩这几个坑
看似简单,但实际用错容易引发 NPE 或难以调试。
- lambda 里别写多行复杂逻辑;提取成命名方法,比如
(a, b) -> computeWithValidation(a, b),方便单元测试 - 涉及可能为空的参数,提前用
Objects.requireNonNull(a, "a must not be null")防御 - 若内部有 IO 或可能抛异常,不要硬塞进 apply;改用 try-catch 包裹,返回 Optional 或默认值
- 注意和 BinaryOperator 的区别:后者是 BiFunction 的子集,要求 T == U == R,比如
BinaryOperator<integer> max = Math::max;</integer>
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











