How to short-circuit reduce on Stream?

前端 未结 1 1738
囚心锁ツ
囚心锁ツ 2021-02-14 10:24

Suppose I have a stream of boolean values and the reduce operation that I am writing is || (OR). Can I write it in a way such that the evaluation of at least some o

1条回答
  •  隐瞒了意图╮
    2021-02-14 10:41

    I suspect you want this type of construct.

    // stop when any element evaluates to true
    boolean any = stream.anyMatch(t -> t);
    

    You can check this with peek

    Stream.of(1, 2, 3, 4).peek(System.out::println).anyMatch(i -> i == 2);
    

    prints

    1
    2
    

    For a parallel example

    AtomicInteger count = new AtomicInteger();
    IntStream.range(0, 1000).parallel().peek(t -> count.incrementAndGet()).anyMatch(i -> i == 2);
    System.out.println("count: " + count);
    

    prints a number like

    count: 223
    

    The exact number varies.

    For a referencePipeline, the anyMatch calls

    @Override
    public final boolean anyMatch(Predicate predicate) {
        return evaluate(MatchOps.makeRef(predicate, MatchOps.MatchKind.ANY));
    }
    

    which calls this

    public static  TerminalOp makeRef(Predicate predicate,
            MatchKind matchKind) {
        Objects.requireNonNull(predicate);
        Objects.requireNonNull(matchKind);
        class MatchSink extends BooleanTerminalSink {
            MatchSink() {
                super(matchKind);
            }
    
            @Override
            public void accept(T t) {
                if (!stop && predicate.test(t) == matchKind.stopOnPredicateMatches) {
                    stop = true;
                    value = matchKind.shortCircuitResult;
                }
            }
        }
    
        return new MatchOp<>(StreamShape.REFERENCE, matchKind, MatchSink::new);
    }
    

    where you can start to see the short circuiting code.

    0 讨论(0)
提交回复
热议问题