I'm generating, let's say, the following range:
IntStream.iterate(1, i -> 3*i)
How do I limit the stream to a specific element value e.g. 100 (not elements count with limit())?
Thank you!
UPDATE the function can be arbitrary
I'm generating, let's say, the following range:
IntStream.iterate(1, i -> 3*i)
How do I limit the stream to a specific element value e.g. 100 (not elements count with limit())?
Thank you!
UPDATE the function can be arbitrary
 
    
    If you can’t use Java 9 yet, you can use the following reimplementation of the three-arg IntStream.iterate:
public static IntStream iterate(int seed, IntPredicate hasNext, IntUnaryOperator next) {
    Objects.requireNonNull(next); Objects.requireNonNull(hasNext);
    return StreamSupport.intStream(
        new Spliterators.AbstractIntSpliterator(
            Long.MAX_VALUE, Spliterator.ORDERED|Spliterator.NONNULL) {
        private IntUnaryOperator op = i -> { op = next; return i; };
        private int value = seed;
        @Override
        public boolean tryAdvance(IntConsumer action) {
            Objects.requireNonNull(action);
            if(op == null) return false;
            int t = op.applyAsInt(value);
            if(!hasNext.test(t)) { op = null; return false; }
            action.accept(value = t);
            return true;
        }
        @Override
        public void forEachRemaining(IntConsumer action) {
            Objects.requireNonNull(action);
            IntUnaryOperator first = op;
            if(first == null) return;
            op = null;
            for(int t = first.applyAsInt(value); hasNext.test(t); t = next.applyAsInt(t))
                action.accept(t);
        }
    }, false);
}
It works similar to Java 9’s IntStream.iterate, except that you have to change the class you’re invoking the static method on (or adapt the import static statement):
iterate(1, i -> i < 100, i -> i*3).forEach(System.out::println);
1
3
9
27
81
 
    
    A new method
Stream<T> iterate(T seed,Predicate<? super T> hasNext,UnaryOperator<T> next)
was introduced in Java-9. So starting with that version it is possible to do something like this:
IntStream.iterate(1, i -> i < 100, i -> 3*i)
Which will produce 1 3 9 27 81
 
    
    As addition to other answers, if you can use java-9 already, there is another possibility using Stream#takeWhile taking a Predicate as parameter.
Tested in jshell
jshell> IntStream.iterate(1, i -> 3 * i).takeWhile(i -> i < 100).toArray();
$3 ==> int[5] { 1, 3, 9, 27, 81 }
 
    
    IntStream.range(0, N).forEach(this::doSomething);
int[] arr = IntStream.range(start, end).toArray();
