Ограничить IntStream.iterate определенным значением - PullRequest
0 голосов
/ 05 июня 2018

Я генерирую, скажем, следующий диапазон:

IntStream.iterate(1, i -> 3*i)

Как ограничить поток определенным значением элемента, например, 100 (не считая элементов с помощью limit ())?

Спасибо!

ОБНОВЛЕНИЕ функция может быть произвольной

Ответы [ 4 ]

0 голосов
/ 05 июня 2018

В дополнение к другим ответам, если вы уже можете использовать , есть еще одна возможность, используя Stream#takeWhile, принимая Predicate в качествепараметр.

Протестировано в

jshell> IntStream.iterate(1, i -> 3 * i).takeWhile(i -> i < 100).toArray();
$3 ==> int[5] { 1, 3, 9, 27, 81 }
0 голосов
/ 05 июня 2018
IntStream.range(0, N).forEach(this::doSomething);


int[] arr = IntStream.range(start, end).toArray();
0 голосов
/ 05 июня 2018

Если вы еще не можете использовать Java 9, вы можете использовать следующую повторную реализацию трех-аргумента 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);
}

Он работает аналогично Java 9 * IntStream.iterate, за исключением того, что вынеобходимо изменить класс, для которого вы вызываете метод static (или адаптировать оператор import static):

iterate(1, i -> i < 100, i -> i*3).forEach(System.out::println);
1
3
9
27
81
0 голосов
/ 05 июня 2018

В Java-9 был представлен новый метод

Stream<T> iterate​(T seed,Predicate<? super T> hasNext,UnaryOperator<T> next)

.Итак, начиная с этой версии, можно сделать что-то вроде этого:

IntStream.iterate(1, i -> i < 100, i -> 3*i)

, который будет производить 1 3 9 27 81

...