【问题标题】:Whats the difference between Optional.flatMap() and Stream.flatMap() [closed]Optional.flatMap() 和 Stream.flatMap() 有什么区别[关闭]
【发布时间】:2018-06-26 10:42:57
【问题描述】:

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

Stream 上的正确 flatMap:

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

在 Optional 上使用 flatMap 时出现异常:

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

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

【问题讨论】:

  • 你在问什么?这真的不清楚,您是否阅读过文档和这里的许多其他帖子?
  • 它们执行非常相似的操作,因此名称相同。主要区别在于一个需要Optional 和一个返回Optional 的方法,而另一个需要一个Stream 和一个返回Stream 的方法。
  • 您能否将您的示例详细说明为MCVE?这会有所帮助。
  • 你说你得到的异常的堆栈跟踪也会有帮助。
  • 您最好澄清您的问题以准确说明您要做什么,并提供自给自足的代码 sn-ps 来显示您的问题 (minimal reproducible example)。即使您已经得到了答案,这也会对未来的读者有所帮助。

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


【解决方案1】:

很难从您的代码 sn-ps 中确定我们不知道您使用的变量的类型或方法的返回类型。但我认为你的错误的根源是你试图将一个返回Stream的lambda传递给Optional.flatMap()

我们先看StreamStream.flatMap() 接受一个返回 Stream 的函数。这似乎正是您在第一个代码 sn-p 中提供的内容。

另一方面,OptionalOptional.flatMap() 需要一个返回 Optional 的函数。如果getBrowse() 返回一个Optional,那么你传递给Optional.flatMap 的是uri -&gt; physicalInventoryClient.getSublocationsByIds(uri).stream()。这看起来像您的 lambda 返回一个流,而不是 Optional。当我在 Eclipse 中尝试相同的操作时,我收到如下编译错误:

方法 flatMap(Function super String,? extends Optional 类型 Optional 中的 extends U>>) 不适用于 参数 ((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() 返回一个列表,但如果返回类型是其他类型,则可以修改它以使其工作。恕我直言,这有点简单。

【讨论】:

  • 对不起,这是我在 stackoverflow 中的第一个问题。这个答案符合我的期望。非常感谢!
  • 我们都在学习。是的,学习如何使用这个网站需要一点时间。欢迎!顺便说一句,我想到了一个不同的解决方案并将其添加到答案中。
【解决方案2】:

OptionalStream 是 2 种不同的野兽,用于不同的目的。

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

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

阅读here了解更多关于Optional.flatMap();的信息

Stream' flatmap() 帮助您获取和处理列表元素的嵌套元素。 Stream 的 flatmap() 的更多解释和解释见 here

【讨论】:

    【解决方案3】:

    来自 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-10
      • 2011-09-20
      • 2013-03-25
      • 2023-03-08
      • 2016-07-17
      • 2015-07-17
      • 2014-07-11
      • 2020-12-28
      相关资源
      最近更新 更多