如何匹配流元素但如果不存在则返回false? [英] How to match stream elements but return false if non exists?
问题描述
我有一个流,想检查是否所有匹配过滤器。如果全部匹配,则返回 true
。
I have a stream and would like to check if all match a filter. If all match, return true
.
但是,如果流为空,我想返回 false
。
But, if the stream is empty, I'd like to return false
.
我该怎么做?
示例代码:
public boolean validate(Stream<Whatever> stream) {
// Problem: returns **true** if stream empty.
// How can **false** be returned if stream is empty?
return stream.allMatch(Whatever::someCheck);
}
推荐答案
你可以用
public boolean validate(Stream<Whatever> stream) {
return stream.map(Whatever::someCheck).reduce(Boolean::logicalAnd).orElse(false);
}
表示意图。我们将每个元素映射到 boolean
值,表示它是否匹配并使用逻辑和操作减少所有元素,这将产生 true
iff所有这些都是 true
。如果没有元素, reduce
将返回一个空的可选
,我们将其映射到 false
按预期使用 orElse(false)
。
which expresses the intent. We map each element to a boolean
value expressing whether it matches and reducing all of them with a logical and operation which will yield true
iff all of them were true
. reduce
will return an empty Optional
if there were no elements, which we map to false
using orElse(false)
, as intended.
唯一的缺点是这是非短路,即不会立即停止在第一个非匹配元件上。
The only disadvantage is that this is non short-circuiting, i.e. does not stop immediately at the first non-matching element.
仍然支持短路的解决方案可能会进一步发展:
A solution still supporting short-circuiting might be a bit more evolved:
public boolean validate(Stream<Whatever> stream) {
boolean parallel = stream.isParallel();
Spliterator<Whatever> sp = stream.spliterator();
if(sp.getExactSizeIfKnown() == 0) return false;
Stream.Builder<Whatever> b = Stream.builder();
if(!sp.tryAdvance(b)) return false;
return Stream.concat(b.build(), StreamSupport.stream(sp, parallel))
.allMatch(Whatever::someCheck);
}
这是 Eugene的回答,但它没有松散的特性或并行性,一般来说可能会更有效率。
This is a variant of Eugene’s answer, but it doesn’t loose characteristics or parallelism and might be a bit more efficient in general.
这篇关于如何匹配流元素但如果不存在则返回false?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!