Function<T, R>是Java中用于类型T到R安全转换的函数式接口,通过apply实现映射,支持andThen/compose链式组合,并与Stream.map天然集成,需注意空值处理与类型安全。

Java 中的 Function<T, R> 是最常用的数据转换型函数式接口,核心作用就是把一个类型 T 的输入,按需加工后返回另一个类型 R 的结果。它不自动做类型转换,但为你提供了清晰、安全、可组合的转换表达方式。
用 apply 实现基础类型或对象映射
所有转换逻辑都写在 apply 方法里,可以是简单方法引用,也可以是带校验的 Lambda 表达式:
- 字符串转整数:
Function<String, Integer> parse = s -> Integer.parseInt(s);(注意空值会抛异常) - 安全解析(含判空):
Function<String, Integer> safeParse = s -> s == null ? 0 : Integer.parseInt(s); - 从对象取属性:
Function<User, String> getName = User::getName; - 自定义构造:
Function<UserDTO, User> toEntity = dto -> new User(dto.getId(), dto.getName());
用 andThen 和 compose 组合多步转换
单个 Function 只做一步,但业务常需链式加工。两个默认方法让组合自然又语义明确:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
andThen:先本函数,再后续函数 —— 适合“先转再处理”:Function<String, Integer> strToLen = String::length;<br>Function<Integer, Integer> square = x -> x * x;<br>Function<String, Integer> lenThenSquare = strToLen.andThen(square);<br>lenThenSquare.apply("hello"); // 返回 25 -
compose:先传入函数,再本函数 —— 更贴近“输入→中间态→输出”的阅读顺序:Function<String, Integer> parseInt = Integer::parseInt;<br>Function<Integer, String> toHex = Integer::toHexString;<br>Function<String, String> strToHex = toHex.compose(parseInt);<br>strToHex.apply("255"); // 返回 "ff"
嵌入 Stream 流水线做声明式数据处理
与 Stream.map() 天然契合,把“怎么遍历”交给 Stream,你只关注“怎么变”:
立即学习“Java免费学习笔记(深入)”;
- 一次性转换列表:
List<String> ids = orders.stream()<br> .map(o -> "[" + o.getId() + "] " + o.getUser().getName())<br> .collect(Collectors.toList());
- 复用逻辑提升可读性:
static final Function<Order, String> ORDER_SUMMARY =<br> o -> String.format("[%d] %s - ¥%.2f", o.getId(), o.getUser().getName(), o.getAmount());<br>// 后续直接用<br>orders.stream().map(ORDER_SUMMARY).toList();
注意空值与类型安全边界
Function 不强制非空,但运行时强转失败或空指针会直接抛异常。关键防护点:
- 避免裸强转:
(String) obj必须配合instanceof检查 - 优先用已有静态方法引用:
Integer::valueOf比Integer::parseInt更明确处理空串语义 - 对可能为 null 的输入,显式处理分支,例如:
Function<LocalDateTime, String> format = dt -> dt == null ? "" : dt.toString(); - 泛型擦除场景下慎用原始类型转换,推荐用更具体的封装类型替代
Object

















