函数式编程“展开”可选或可选。在Java流(或并行流)中返回前为空
我在这件简单的事情上遇到了麻烦。我有一个返回Optional<TypeA>
的方法:
public Optional<TypeA> getFirst() {
return set.stream().filter(it -> it.getStatus() == SUCCESS).findFirst(); // set is a Set<TypeA>
}
。。。那么,我从以下位置调用它:
public boolean hasFirst() {
return types.parallelStream() // types is a List<TypeB> that has a Set<TypeA>
.filter(it -> it.getTotalAmount() > 0)
.map(TypeA::getFirst)
.findFirst() // this can return an Optional[Optional.empty]
.isPresent();
}
问题是,一个空的Optional
的Optional
像预期的那样返回true
,所以我不知道如何正确处理这个问题
有什么线索吗
# 1 楼答案
要将
Optional<Optional<Foo>>
折叠为Optional<Foo>
,可以使用orElse
,如下所示:因此,对于您的示例,您可以添加。orElse到您的流调用:
# 2 楼答案
使用
.findFirst().isPresent()
是一种常见的反模式。如果您只想知道是否存在匹配项,则无需询问第一个匹配项,尤其是,如果您打算使用并行流,搜索第一个匹配项而不是任何匹配项可能会有显著的性能缺陷。因此findAny
更可取,但当您只想知道是否存在匹配项时,根本不需要询问值:不清楚,您的原始代码应该如何工作,如果
types
是一个TypeB
实例的列表,而getFirst()
是在TypeA
中声明的一个方法,正如TypeA::getFirst
所指出的,但是,我认为,您明白了我还建议将方法
hasFirst()
重命名为hasAny()
。当然,具有任何匹配元素的集合也将具有第一个元素,但将注意力集中在“第一个”上会产生误导,特别是当TypeA
元素位于Set
中时,这通常意味着根本没有定义的顺序# 3 楼答案
您可以使用^{} 来“展开”内部可选文件: