How to match stream elements but return false if non exists?

AlikElzin-kilaka :

I have a stream and would like to check if all match a filter. If all match, return true.

But, if the stream is empty, I'd like to return false.

How can I do this?

Example code:

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);
}
Holger :

You could use

public boolean validate(Stream<Whatever> stream) {
    return stream.map(Whatever::someCheck).reduce(Boolean::logicalAnd).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);
}

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.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=436980&siteId=1