Optional.flatMap((和 Stream.flatMap(( 有什么区别?
正确的流平面地图:
List<ObjectDTO> collect = types.stream()
.flatMap(a -> client.getSthById(new URI(a)).stream())
.collect(Collectors.toList());
在可选上使用平面地图时的异常:
List<ObjectDTO> collect2 = client.getSthByObj(obje.get(), null).getBrowse()
.flatMap(uri -> client.getSthById(uri).stream())
.collect(Collectors.toList());
为什么我不能以同样的方式使用它?
Optional
和Stream
是两种不同的野兽,用于不同的目的。
Optional
是一个包装器,它保存一个可以"存在"或不存在"(null
(的结果,并提供处理这两个条件(存在或不存在(的方法。
flatMap()
操作是应用于Optional
包装器中保存的值的操作。该操作必须返回Optional
结果:
Optional<String> s = Optional.of("test input");
s.flatMap( input -> Optional.of(input));
Stream 的flatMap()
可帮助您获取和处理列表元素的嵌套元素。
附加阅读
- Optional.flatMap 和 Optional.map 有什么区别?
- Java 8 中的 map(( 和 flatMap(( 方法有什么区别?
很难从您的代码片段中确定我们不知道您使用的变量的类型,也不知道方法的返回类型。但我认为您的错误来源是您试图传递一个返回Stream
的 lambdaOptional.flatMap()
.
让我们先看看Stream
。Stream.flatMap()
采用一个返回Stream
的函数。这似乎正是您在第一个代码片段中给出的内容。
另一方面Optional
:Optional.flatMap()
需要一个返回Optional
的函数。如果getBrowse()
返回一个Optional
,那么你传递给Optional.flatMap
的内容是uri -> physicalInventoryClient.getSublocationsByIds(uri).stream()
。这看起来像您的 lambda 返回流,而不是Optional
。当我在 Eclipse 中尝试相同的操作时,我收到如下编译错误:
方法flatMap(Function<? super String,? extend Optional<? 扩展 U>>( 类型中的 可选<字符串>不适用于 参数 ((对象 x( -> {}(字符串>
解决方案是什么?从Java 9开始,Optional
有一个stream
的方法,可能会让你实现你正在尝试的事情。同样,如果不了解您的代码,很难提出建议,但可能是这样的:
List<SublocationBrowseDTO> collect2 = physicalInventoryClient.getSublocationsByLocation(masterLocation.get(), null)
.getBrowse()
.stream()
.flatMap(uri -> physicalInventoryClient.getSublocationsByIds(uri).stream())
.collect(Collectors.toList());
编辑:没有流的替代:
List<SublocationBrowseDTO> collect2 = physicalInventoryClient.getSublocationsByLocation(masterLocation.get(), null)
.getBrowse()
.map(uri -> physicalInventoryClient.getSublocationsByIds(uri))
.orElse(Collections.emptyList());
后一个版本要求getSublocationsById()
返回一个列表,但如果返回类型是其他类型,则可能可以修改为工作。恕我直言,它更简单一些。
来自 javadoc: 可选.平面地图:
flatMap(Function<? super T,Optional<U>> mapper)
如果存在值,则对其应用提供的可选方位映射函数,返回该结果,否则返回空的 Optional。
Stream.flatMap:
flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
返回一个流,该流包含将此流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果。
所以主要区别在于,一个返回一个流,另一个返回一个可选