Java函数式编程:双输入参数的Optional Monad Map实现疑问
关于双参数函数结合Optional的操作
你说的这个操作在函数式编程里叫做函数提升(Lifting),具体是将普通的二元函数(接受两个非Optional类型参数)提升为可以处理Optional类型的函数——仅当所有输入的Optional都包含值时才执行原函数,否则返回Optional.empty()。另外从范畴论角度,这属于Applicative Functor的应用场景,不过Java标准库的Optional并没有直接提供Applicative相关API,但可以通过现有方法实现需求。
在Java中,有几种常见的实现方式:
1. 嵌套使用flatMap + map
这是最直接的实现方式,利用flatMap处理第一个Optional,在其内部用map处理第二个Optional:
int getData(Connection conn, int data) { ... } var data = Optional.of(100); var connection = getOptionalDataConnection(); // 仅当connection和data都不为空时,才调用getData var result = connection.flatMap(conn -> data.map(i -> getData(conn, i)));
- 若
connection为空,flatMap直接返回Optional.empty() - 若
connection有值但data为空,map返回Optional.empty() - 只有两者都有值时,才会执行
getData并返回包装后的结果
2. 利用Optional.stream()(Java 9+)
将Optional转换为Stream,通过Stream的操作实现双值组合:
var result = connection.stream() .flatMap(conn -> data.stream().map(i -> getData(conn, i))) .findFirst();
- 空的Optional转换后是空Stream,因此只要任一输入为空,整个Stream操作结果为空,
findFirst返回Optional.empty() - 两者都有值时,Stream会生成对应计算结果,
findFirst将其包装为Optional返回
3. 封装自定义工具方法
如果需要频繁使用这类操作,可以封装一个通用工具方法:
import java.util.Optional; import java.util.function.BiFunction; public class OptionalUtils { public static <A, B, R> Optional<R> map2(Optional<A> optA, Optional<B> optB, BiFunction<A, B, R> function) { return optA.flatMap(a -> optB.map(b -> function.apply(a, b))); } }
调用时更简洁:
var result = OptionalUtils.map2(connection, data, this::getData);
内容的提问来源于stack exchange,提问作者Mahdi
相关产品推荐
相关产品推荐

