Java中 BiFunction 接口 apply 方法怎样处理双参数

作者:袖梨 2026-07-21
apply方法严格按BiFunction<T,U,R>接口要求接收两个参数并返回单一结果,不自动解包、不隐式转换、不校验空值,类型匹配和逻辑由用户定义,无状态、无拦截、不可隐式转型。

apply 方法直接接收两个参数,按声明顺序传入,执行逻辑后返回单一结果。 它不自动解包、不隐式转换、不校验空值——所有行为都由你写的 lambda 或方法引用决定。关键在于类型匹配和逻辑聚焦。

参数顺序和类型必须严格对应接口声明

BiFunction<T, U, R> 的 apply(T t, U u) 要求:第一个实参类型必须是 T,第二个必须是 U。比如:

  • BiFunction<String, Integer, User> creator = User::new; —— 构造器必须接受 String 作第一参、Integer 作第二参,否则编译失败
  • BiFunction<List<String>, Integer, String> getNth = (list, idx) -> list.get(idx); —— 若传入 (idx, list),类型错位,编译报错

执行过程就是一次函数调用,无额外包装或调度

apply 不做拦截、不加日志、不重试。它等价于手动调用你定义的逻辑:

  • BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
    调用 add.apply(3, 5) 就是直接计算 3 + 5,返回 8
  • BiFunction<User, String, Boolean> hasRole = (u, r) -> u != null && u.getRoles().contains(r);
    调用时若 u 为 null,就会触发 NullPointerException —— 空安全需自行处理

返回值类型由泛型 R 决定,不可隐式转型

编译器强制返回值必须是 R 类型或其子类。常见误用:

立即学习“Java免费学习笔记(深入)”;

  • 声明为 BiFunction<String, String, Number>,却在 lambda 中返回 "123"(String 不是 Number 子类)→ 编译失败
  • 正确写法:BiFunction<String, String, String> concat = (a, b) -> a + b; 或 BiFunction<String, String, Number> lenSum = (a, b) -> a.length() + b.length();

它不维护状态,每次 apply 都是独立计算

BiFunction 实例本身无成员变量,不记录上次调用结果。适合纯函数场景:

  • 可安全共享、复用、传递给 Stream.map
  • 无法靠自身实现“累计求和”或“记住上一个输入”,这类需求需配合外部变量或改用其他结构

相关文章

精彩推荐