如何将 Optional<T> 转换为 Stream<T>?

Posted

技术标签:

【中文标题】如何将 Optional<T> 转换为 Stream<T>?【英文标题】:How to convert an Optional<T> into a 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

【问题讨论】:

见***.com/questions/22725537/… 这个问题确实回答了这个问题,但它提供了一个更复杂的例子。我认为这个简单的案例值得保留。 【参考方案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 上,我可以推荐 Guava 的 Streams.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));

【讨论】:

以上是关于如何将 Optional<T> 转换为 Stream<T>?的主要内容,如果未能解决你的问题,请参考以下文章

将一个 std::optional 转换为另一个 std::optional

如何使用 std::optional<T>::emplace 的第二个重载

从 Optional<> 转换为 ArrayList<>

如何将通用 List<T> 转换为基于接口的 List<T>

如何将 IEnumerable<t> 或 IQueryable<t> 转换为 EntitySet<t>?

如何轻松将 DataReader 转换为 List<T>? [复制]