Limit a stream by a predicate

前端 未结 19 3401
别跟我提以往
别跟我提以往 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:56

    Update: Java 9 Stream now comes with a takeWhile method.

    No needs for hacks or other solutions. Just use that!


    I am sure this can be greatly improved upon: (someone could make it thread-safe maybe)

    Stream stream = Stream.iterate(0, n -> n + 1);
    
    TakeWhile.stream(stream, n -> n < 10000)
             .forEach(n -> System.out.print((n == 0 ? "" + n : "," + n)));
    

    A hack for sure... Not elegant - but it works ~:D

    class TakeWhile implements Iterator {
    
        private final Iterator iterator;
        private final Predicate predicate;
        private volatile T next;
        private volatile boolean keepGoing = true;
    
        public TakeWhile(Stream s, Predicate p) {
            this.iterator = s.iterator();
            this.predicate = p;
        }
    
        @Override
        public boolean hasNext() {
            if (!keepGoing) {
                return false;
            }
            if (next != null) {
                return true;
            }
            if (iterator.hasNext()) {
                next = iterator.next();
                keepGoing = predicate.test(next);
                if (!keepGoing) {
                    next = null;
                }
            }
            return next != null;
        }
    
        @Override
        public T next() {
            if (next == null) {
                if (!hasNext()) {
                    throw new NoSuchElementException("Sorry. Nothing for you.");
                }
            }
            T temp = next;
            next = null;
            return temp;
        }
    
        public static  Stream stream(Stream s, Predicate p) {
            TakeWhile tw = new TakeWhile(s, p);
            Spliterator split = Spliterators.spliterator(tw, Integer.MAX_VALUE, Spliterator.ORDERED);
            return StreamSupport.stream(split, false);
        }
    
    }
    

提交回复
热议问题