Limit a stream by a predicate

前端 未结 19 3136
别跟我提以往
别跟我提以往 2020-11-21 22:54

Is there a Java 8 stream operation that limits a (potentially infinite) Stream until the first element fails to match a predicate?

In Java 9 we can use

19条回答
  •  暗喜
    暗喜 (楼主)
    2020-11-21 23:48

    Here is a version done on ints - as asked in the question.

    Usage:

    StreamUtil.takeWhile(IntStream.iterate(1, n -> n + 1), n -> n < 10);
    

    Here's code for StreamUtil:

    import java.util.PrimitiveIterator;
    import java.util.Spliterators;
    import java.util.function.IntConsumer;
    import java.util.function.IntPredicate;
    import java.util.stream.IntStream;
    import java.util.stream.StreamSupport;
    
    public class StreamUtil
    {
        public static IntStream takeWhile(IntStream stream, IntPredicate predicate)
        {
            return StreamSupport.intStream(new PredicateIntSpliterator(stream, predicate), false);
        }
    
        private static class PredicateIntSpliterator extends Spliterators.AbstractIntSpliterator
        {
            private final PrimitiveIterator.OfInt iterator;
            private final IntPredicate predicate;
    
            public PredicateIntSpliterator(IntStream stream, IntPredicate predicate)
            {
                super(Long.MAX_VALUE, IMMUTABLE);
                this.iterator = stream.iterator();
                this.predicate = predicate;
            }
    
            @Override
            public boolean tryAdvance(IntConsumer action)
            {
                if (iterator.hasNext()) {
                    int value = iterator.nextInt();
                    if (predicate.test(value)) {
                        action.accept(value);
                        return true;
                    }
                }
    
                return false;
            }
        }
    }
    

提交回复
热议问题