![Java核心技术·卷Ⅱ:高级特性(原书第10版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/937/34339937/b_34339937.jpg)
1.7.4 用flatMap来构建Optional值的函数
假设你有一个可以产生Optional<T>对象的方法f,并且目标类型T具有一个可以产生Optional<U>对象的方法g。如果它们都是普通的方法,那么你可以通过调用s.f().g()来将它们组合起来。但是这种组合没法工作,因为s.f()的类型为Optional<T>,而不是T。因此,需要调用:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/013-2-i.jpg?sign=1739360904-h1nDg2dvuoXbxYHEq4LGuPzlI4WkctIT-0-efea5ca144556b1ca4bf6b6e15287954)
如果s.f()的值存在,那么g就可以应用到它上面。否则,就会返回一个空Optional<U>。
很明显,如果有更多的可以产生Optional值的方法或Lambda表达式,那么就可以重复此过程。你可以直接将对flatMap的调用链接起来,从而构建由这些步骤构成的管道,只有所有步骤都成功时,该管道才会成功。
例如,考虑前一节中安全的inverse方法。假设我们还有一个安全的平方根:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/013-3-i.jpg?sign=1739360904-gk7HRdzsvzjlCSwWeS32Xu9UmE38mvaY-0-0ec47ea14ef02e0b2f9d7209913b52aa)
那么你可以像下面这样计算倒数的平方根了:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/014-i.jpg?sign=1739360904-T2qFQJn6hj9BsyjJeJOeaSRSksSKtAZQ-0-161a9a252b6021a1e1d86419aea4ae3b)
或者,你可以选择下面的方式:
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/014-2-i.jpg?sign=1739360904-c1TDVmFVK0u5T2kCsFUHtJWuOJA9gaPT-0-13765a91fa3ce455312960e5852a9320)
无论是inverse方法还是squareRoot方法返回Optional.empty(),整个结果都会为空。
注意:你已经在Stream接口中看到过flatMap方法(参见1.3节),当时这个方法被用来将可以产生流的两个方法组合起来,其实现方式是摊平由流构成的流。如果将可选值当作尺寸为0和1的流来解释,那么Optional.flatMap方法与其操作方式一样。
程序清单1-3中的示例程序演示了Optional API的使用方式。
程序清单1-3 optional/OptionalTest.java
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/014-3-i.jpg?sign=1739360904-j7O0CfMTxW8oMcxo084QbhUyrxCAUHt4-0-c9613c10de130a42f1770d4753bef853)
![](https://epubservercos.yuewen.com/F21227/18365861501241106/epubprivate/OEBPS/Images/015-i.jpg?sign=1739360904-zqf6yJH4lcrBp4t6OdC8gCNDpSLOzcT4-0-f6803f89a488a0a05fcb20473e5d3c0c)
java.util.Optional 8
·<U>Optional<U>flatMap(Function<?super T,Optional<U>>mapper)
产生将mapper应用于当前的Optional值所产生的结果,或者在当前Optional为空时,返回一个空Optional。