Optional.flatMap()和Stream.flatMap()有什么区别

时间:2018-06-26 10:42:57

标签: java methods java-8 java-stream optional

Optional.flatMap()和Stream.flatMap()有什么区别。

在Stream上更正flatMap:

    List<ObjectDTO> collect = types.stream()
            .flatMap(a -> client.getSthById(new URI(a)).stream())
            .collect(Collectors.toList());

在可选上使用flatMap时发生异常:

        List<ObjectDTO> collect2 = client.getSthByObj(obje.get(), null).getBrowse()
                .flatMap(uri -> client.getSthById(uri).stream())
                .collect(Collectors.toList());

为什么不能以相同的方式使用它?

3 个答案:

答案 0 :(得分:1)

Optional Stream 是两种用于分离目的的野兽。

Optional是一个包装器,其中包含可以为“不存在”(空)的结果,并提供了处理这两个条件(“存在”或“不存在”)的方法。 “ flatMap()”操作是应用于可选包装中保存的值的操作。该操作必须返回Optional作为结果:

Optional<String> s = Optional.of("test input");
s.flatMap( input -> Optional.of(input));

阅读here以获得有关Optional.flatMap();的更多信息

Stream' flatmap()帮助您获取和处理列表元素的嵌套元素。有关{em> Stream的flatmap()的更多说明和解释,请参见here

答案 1 :(得分:1)

很难从您的代码段中确定我们不知道您使用的变量的类型还是方法的返回类型。但是我认为,您出错的原因是您试图传递一个将Stream返回给Optional.flatMap()的lambda。

让我们首先看看StreamStream.flatMap()采用返回Stream的函数。这似乎正是您在第一个代码段中所提供的。

另一方面,

OptionalOptional.flatMap()需要一个返回Optional的函数。如果getBrowse()返回Optional,则传递给Optional.flatMap的是uri -> physicalInventoryClient.getSublocationsByIds(uri).stream()。看起来您的lambda返回了一个流,而不是Optional。当我在Eclipse中尝试相同操作时,出现如下编译错误:

  

flatMap(Function <?super String ,?扩展了Optional <?   扩展U >>),类型Optional 不适用于   参数((Object x)-> {})

解决方案?在Java 9中,Optional具有a stream method,这可能会让您实现所尝试的目标。同样,在不知道您的代码的情况下,很难建议您,但是可能是这样的:

    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()返回一个列表,但是如果返回类型是其他类型,则可以对其进行修改以起作用。恕我直言,这有点简单。

答案 2 :(得分:0)

从javadoc: Optional.flatMap:

flatMap(Function<? super T,Optional<U>> mapper)

如果存在一个值,则对它应用提供的Optional-bearing映射函数,返回该结果,否则返回一个空的Optional。

Stream.flatMap:

flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

返回一个流,该流包括将流中的每个元素替换为通过对每个元素应用提供的映射函数而生成的映射流的内容的结果。

所以主要区别是,一个返回一个Stream,另一个返回Optional