【问题标题】:How to convert an Optional<T> into a Stream<T>?如何将 Optional<T> 转换为 Stream<T>?
【发布时间】:2016-02-29 18:48:59
【问题描述】:

我想在流前面添加一个 Optional。由于Stream.concat 只能连接 Streams 我有这个问题:

如何将 Optional 转换为 Stream

例子:

Optional<String> optional = Optional.of("Hello");
Stream<String> texts = optional.stream(); // not working

【问题讨论】:

标签: java java-8 java-stream optional


【解决方案1】:

如果受 Java-8 限制,您可以这样做:

Stream<String> texts = optional.map(Stream::of).orElseGet(Stream::empty);

【讨论】:

  • 我对此表示赞同,因为 Java 9 对某些处于当前状态的项目进行了一些非向后兼容的更改。一些项目,例如lombok,是核心企业工件的一部分,更改缓慢。
  • 如果您的可选项碰巧包含List&lt;String&gt; 而不是单个String 对象,您只需将Stream::of 替换为List::stream。这同样适用于任何其他类型的集合。您也可以只使用Collection::stream。否则你会得到一个Stream&lt;List&lt;String&gt;&gt;,这可能不是你想要的。
  • @walen 问题是将Optional&lt;T&gt; 转换为Stream&lt;T&gt;,如果T 是List&lt;String&gt;,就这样吧。答案仍然正确。您可能正在寻找的是扁平化集合。另外,如果您最终使用了Optional&lt;Collection&lt;T&gt;&gt;,那么您已经走错了路。
  • @Naman 无需证明答案是正确的——我没有说它不正确。我只是提供了一个关于如何将此解决方案应用于包含ListOptional 的提示,这是某些人可能会遇到的情况。
【解决方案2】:

在 Java-9 中添加了缺少的 stream() 方法,所以这段代码可以工作:

Stream<String> texts = optional.stream();

JDK-8050820。下载 Java-9 here

【讨论】:

    【解决方案3】:

    你可以这样做:

    Stream<String> texts = optional.isPresent() ? Stream.of(optional.get()) : Stream.empty();
    

    【讨论】:

    • 我不是isPresent 的忠实粉丝,它对我来说感觉像是一种遗留方法,让我想起了Java8 之前的时代。但感谢您提供替代解决方案。
    • 不如map().orElseGet() 方法流畅,但效率可能略高。
    【解决方案4】:

    如果您不在 Java 9 上,我可以推荐 GuavaStreams.stream(optional) 方法。一个简单的例子:

    Streams.stream(Optional.of("Hello"))
    

    也可以静态导入Streams.stream,这样就可以写了

    stream(Optional.of("Hello"))
    

    【讨论】:

      【解决方案5】:

      如果您使用的是旧版本的 Java(看着你,Android)并且使用 aNNiMON Lightweight Stream API,您可以执行以下操作:

          final List<String> flintstones = new ArrayList<String>(){{
              add("Fred");
              add("Wilma");
              add("Pebbles");
          }};
      
          final List<String> another = Optional.ofNullable(flintstones)
                  .map(Stream::of)
                  .orElseGet(Stream::empty)
                  .toList();
      

      这个例子只是复制了一个列表。

      【讨论】:

        【解决方案6】:

        我的一位前同事提供的一个不错的库是 Streamify。很多收藏家,从几乎所有东西中创建流。

        https://github.com/sourcy/streamify

        在streamify中创建一个可选的流形式:

        Streamify.stream(optional)
        

        【讨论】:

          【解决方案7】:

          这取决于您希望如何将空的可选项转换为流元素。 如果您想将其解释为“无”(或“无元素”):

          Stream<String> texts = optional.stream(); // since JDK 9
          Stream<String> texts = optional.map(Stream::of).orElseGet(Stream::empty); // JDK 8
          

          但是如果你想把它解释为null:

          Stream<String> texts = Stream.of(optional.oreElse(null));
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-11-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-15
            • 2021-10-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多