Java 是否有从可选到流的方便映射方法?

Java 是否有从可选到流的方便映射方法?,java,java-stream,optional,Java,Java Stream,Optional,我有一个返回可选的方法,如果它存在,我想使用该值查找流 现在我知道我可以做到: optionalFoo.map(foo->bars(foo)).orElse(Stream.empty()); optionalFoo.stream().flatMap(foo->bars(foo)); (我正在使用映射函数的完整形式,而不是用于说明的方法参考。) 使用Java 9+我可以做到这一点: optionalFoo.map(foo->bars(foo)).orElse(Stream.e

我有一个返回
可选
的方法,如果它存在,我想使用该值查找

现在我知道我可以做到:

optionalFoo.map(foo->bars(foo)).orElse(Stream.empty());
optionalFoo.stream().flatMap(foo->bars(foo));
(我正在使用映射函数的完整形式,而不是用于说明的方法参考。)

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

optionalFoo.map(foo->bars(foo)).orElse(Stream.empty());
optionalFoo.stream().flatMap(foo->bars(foo));
但无论如何,额外的步骤似乎毫无意义。是否有一种映射方法可以简单地将可选项映射到流,或者如果可选项不存在,则映射到空流?然后我可以做:

optionalFoo.streamMap(foo->bars(foo));
如果没有这样的方法,为什么不呢?它可以作为一个简单的默认方法添加到
Optional

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

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

/**
 * 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);
为什么我需要额外的丑陋
.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));
}
/**
*在HTML文档中查找{@code}元素。
*@param记录文档树。
*@返回树中存在的{@code}元素流。
*/
公共静态流htmlHeadMetaElements(@Nonnull final Document){
return findHtmlHeadElement(文档).streamMap(headElement->
ChildElementsByNames(headElement,XHTML_名称空间_URI_字符串,ELEMENT_META));
}
您可能会说“您不能有从
Optional
到其他所有类型的特殊映射方法”,但是
Optional
Stream
有一种特殊的关系。事实上,我有点认为
可选的
几乎是一个
,包含零个或一个元素。事实上,这正是
Optional.stream()
给出的结果。因此,这是对
Optional.stream()

问题的补充:“为什么‘他们’不将此方法添加到Optional?”,首先是一个旁白

“人格”是什么意思

你会在字典里找到很多定义,但绝对没有一个是词源正确的,那就是“面具”。你看,人物角色来自“每声纳”:你通过它说话。面具

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

返回可选

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

社区中的一些人并不是这样使用它的。有些人将其视为scala的可选选项:将空性信息带入类型系统的“解决方案”

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

通常,任何更新一种语言的提议,如果仅仅需要几乎所有现有的库来发布一个突破性的更新,那将是非常不充分的。然而,如果整个社区都采纳了可选返回值应该通过API以返回
可选
的形式传递的概念,那么这正是需要的

换句话说,“他们”(主要是甲骨文,以及JCP的其他成员)绝对不认为这是可选的

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

现在怎么办?关于如何修复java中的“null”,我有各种各样的想法,不过首先您应该讨论它是否是一个需要修复的问题。远远超出了这个问题的范围


然而,希望这封关于java的null和可选性如何不是它的替代品的信件能够解释为什么Oracle或JCP中的任何其他人不“只是”将一些方法堆到
j.u.Optional
中,以使其更适合用作从API返回可选值的通用机制:因为他们认为(我完全正确地假设,optional不应用于此

这不也取决于
条(foo)
的签名吗?问题的关键是要有与之相关的详细信息。例如,它将如何处理这种情况
流(optionalFoo).平面图(a->bar(a.orElse(null))
。不管怎样,我真的不认为有必要从一个可选的
流图中创建这样一个
流图。可能只是基于观点,但从目前的情况来看,用例不是很清楚