如何将 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
例子:
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<String>
而不是单个String
对象,您只需将Stream::of
替换为List::stream
。这同样适用于任何其他类型的集合。您也可以只使用Collection::stream
。否则你会得到一个Stream<List<String>>
,这可能不是你想要的。
@walen 问题是将Optional<T>
转换为Stream<T>
,如果T 是List<String>
,就这样吧。答案仍然正确。您可能正在寻找的是扁平化集合。另外,如果您最终使用了Optional<Collection<T>>
,那么您已经走错了路。
@Naman 无需证明答案是正确的——我没有说它不正确。我只是提供了一个关于如何将此解决方案应用于包含List
的Optional
的提示,这是某些人可能会遇到的情况。【参考方案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 的第二个重载
如何将通用 List<T> 转换为基于接口的 List<T>