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

后端 未结 6 1733
无人共我
无人共我 2020-12-09 11:58

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

6条回答
  •  遥遥无期
    2020-12-09 12:30

    You could use

    public boolean validate(Stream 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 stream) {
        boolean parallel = stream.isParallel();
        Spliterator sp = stream.spliterator();
        if(sp.getExactSizeIfKnown() == 0) return false;
        Stream.Builder 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.

提交回复
热议问题