How to short-circuit a reduce() operation on a Stream?

前端 未结 3 1568
盖世英雄少女心
盖世英雄少女心 2020-12-01 06:31

This is essentially the same question as How to short-circuit reduce on Stream?. However, since that question focuses on a Stream of boolean values, and its answer cannot be

3条回答
  •  时光取名叫无心
    2020-12-01 06:58

    A general short-circuiting static reduce method can be implemented using the spliterator of a stream. It even turned out to be not very complicated! Using spliterators seems to be the way to go a lot of times when one wants to work with steams in a more flexible way.

    public static  T reduceWithCancel(Stream s, T acc, BinaryOperator op, Predicate cancelPred) {
        BoxConsumer box = new BoxConsumer();
        Spliterator splitr = s.spliterator();
    
        while (!cancelPred.test(acc) && splitr.tryAdvance(box)) {
            acc = op.apply(acc, box.value);
        }
    
        return acc;
    }
    
    public static class BoxConsumer implements Consumer {
        T value = null;
        public void accept(T t) {
            value = t;
        }
    }
    

    Usage:

        int product = reduceWithCancel(
            Stream.of(1, 2, 0, 3, 4).peek(System.out::println),
            1, (acc, i) -> acc * i, i -> i == 0);
    
        System.out.println("Result: " + product);
    

    Output:

    1
    2
    0
    Result: 0
    

    The method could be generalised to perform other kinds of terminal operations.

    This is based loosely on this answer about a take-while operation.

    I don't know anything about the parallelisation potential of this.

提交回复
热议问题