如何匹配流元素但如果不存在则返回false?

Ali*_*aka 10 java java-8 java-stream

我有一个流,想检查是否所有匹配过滤器.如果全部匹配,则返回true.

但是,如果流是空的,我想回来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);
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 16

你可以用

public boolean validate(Stream<Whatever> stream) {
    return stream.map(Whatever::someCheck).reduce(Boolean::logicalAnd).orElse(false);
}
Run Code Online (Sandbox Code Playgroud)

表达了意图.我们将每个元素映射到一个boolean值,表示它是否匹配并使用逻辑操作减少所有元素,这将产生trueiff所有它们true.如果没有我们映射到使用的元素,reduce将返回一个空的,如预期的那样.OptionalfalseorElse(false)

唯一的缺点是这是非短路的,即不会立即停在第一个非匹配元件上.

仍然支持短路的解决方案可能会进一步发展:

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);
}
Run Code Online (Sandbox Code Playgroud)

这是Eugene答案的变体,但它并没有松散特征或并行性,一般来说可能会更有效.

  • 您可以用任何化合物验证替换`Whatever :: someCheck`.链接多个`filter`调用与通过`&&`组合条件没有区别,例如在lambda表达式中.您的初始方法也无法实现除创建复合谓词之外的其他解决方案.在您调用`allMatch`之后,流已被使用,并且无法进行其他验证. (3认同)