gpt4 book ai didi

java - 有没有方便的从Optional到Stream的映射方法?

转载 作者:行者123 更新时间:2023-11-30 12:06:40 25 4
gpt4 key购买 nike

我有一个返回 Optional<Foo> 的方法,如果它存在,我想使用该值来查找 Stream<Bar> .

现在我知道我可以做到:

optionalFoo.map(foo->bars(foo)).orElse(Stream.empty());

(我使用映射函数的完整形式而不是方法引用来进行说明。)

使用 Java 9+ 我可以做到这一点:

optionalFoo.stream().flatMap(foo->bars(foo));

但不管怎样,额外的步骤似乎毫无意义。是否有一种映射方法可以简单地将可选映射到流,或者如果可选不存在则映射到空流?然后我可以这样做:

optionalFoo.streamMap(foo->bars(foo));

如果没有这样的方法,为什么不呢?它可以作为简单的默认方法添加到 Optional 上.

最后,如果我必须编写自己的实用方法,以上哪种方法更有效(看到它们都提供相同的结果):映射到流或空流;或转换为流然后平面映射到流?我会假设前者更有效,这说明了为什么需要实用方法。 (我们不想到处重新输入 .orElse(Stream.empty())。)

对于那些需要具体用例的人,假设有一种方法可以返回 HTML <head>来自 DOM 树的元素:

/**
* Finds the {@code <html><head>} element in the HTML namespace.
* @param document The document tree.
* @return A reference to the {@code <html><head>} element if it exists in the tree.
*/
public static Optional<Element> findHtmlHeadElement(@Nonnull final Document document);

现在另一个方法想要返回所有的 HTML <meta>元素(如果存在)。所以它想搜索 ​​<head> 的 child 元素,当然前提是它存在。 (请注意,childElementsByNameNS() 是一种实用方法,可将另一个元素的子元素检索为 Stream<Element>。)

/**
* Finds the {@code <html><head><meta>} elements in an HTML document.
* @param document The document tree.
* @return A stream of {@code <html><head><meta>} elements if they exist in the tree.
*/
public static Stream<Element> htmlHeadMetaElements(@Nonnull final Document document) {
return findHtmlHeadElement(document).map(headElement ->
childElementsByNameNS(headElement, XHTML_NAMESPACE_URI_STRING, ELEMENT_META))
.orElse(Stream.empty());
}

为什么我需要额外丑陋的.orElse(Stream.empty())样板?我宁愿有这样的东西:

/**
* Finds the {@code <html><head><meta>} elements in an HTML document.
* @param document The document tree.
* @return A stream of {@code <html><head><meta>} elements if they exist in the tree.
*/
public static Stream<Element> htmlHeadMetaElements(@Nonnull final Document document) {
return findHtmlHeadElement(document).streamMap(headElement ->
childElementsByNameNS(headElement, XHTML_NAMESPACE_URI_STRING, ELEMENT_META));
}

您可能会说“您不能使用从 Optional 到所有其他类型的特殊映射方法”,但是 OptionalStream有着特殊的关系。事实上我有点想到Optional几乎是Stream具有零个或一个元素。事实上,这正是 Optional.stream()回馈。所以这真的是对 Optional.stream() 的补充.

最佳答案

关于这个问题:“‘他们’为什么不把这个方法添加到可选的?”,首先是一个旁白。

“角色”是什么意思?

您会在字典中找到许多定义,但绝对没有一个词源上是正确的,即“面具”。你看,角色来自“personare”:你说话的东西。一个面具。

可以说,persona 这个词的“作者”认为它的意思是“面具”。但是语言是动态的东西,其真正含义可能更多地取决于单词的使用方式,而不是作者的意思。

返回可选。

optional 的作者(Brian Goetz 和 Oracle 的 Lambda 项目的其他成员)将其编写为流操作终端的解决方案,这对于空流可能没有意义。 list.stream().max(someComparator) 的返回值是多少?如果列表为空?就是这样。这就是全部 j.u.Optional曾经是为了。

社区中的一些人并不完全那样使用​​它。有些人更像是将它视为 scala 的可选:作为将无效信息携带到类型系统中的“解决方案”。

这是非常不明智的。也许 null 作为一个动态概念有问题并且存在更好的解决方案(值得商榷,但超出了这个问题的范围,而不是重点),但是鉴于绝对没有研究或思考,下意识地选择 Optional 作为答案是显然不好。我们已经可以看到这一点:Java 拥有 20 年成为地球上最流行的语言之一的历史,并且正如人们所期望的那样建立了一个巨大的库生态系统。您无法替换返回 X 的 API返回 Optional<X>以向后兼容的方式,这意味着这 20 年的库中几乎每一个最后一个库都需要像昨天的垃圾一样被删除,因为没有办法转换 API。

通常,任何更新语言的提议都要求几乎所有现有的库都编写过以发布重大更新,这都是可笑的不足。然而,如果整个社区都接受这样一种观念,即应通过 API 以返回 Optional<T> 的形式传送可选返回值,那么这正是所需要的。 .

换句话说,“他们”(主要是 Oracle,以及 JCP 的其他成员)绝对不认为 Optional 应该用于什么目的。

然而,社区确实在使用它。 Oracle 仍然认为它的意思是“面具”,一半的社区坚持认为它肯定是“面具”的意思,但社区的另一半​​开始使用“角色”来表示戏剧中角色的概念。

现在呢?关于如何修复 java 中的“null”,我有多种想法,但首先你应该讨论它是否是一个需要修复的问题。远远超出了这个问题的范围。

但是,希望这篇关于 java 的 null 以及 Optional 为何不能替代它的文章能够阐明为什么 Oracle 或 JCP 中的其他任何人不“只是”将一些方法堆放在 j.u.Optional 中。使其更适合将其用作从 API 返回可选值的通用机制:因为他们认为(我认为完全正确)不应该为此使用可选值。。 p>

关于java - 有没有方便的从Optional到Stream的映射方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55432947/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com