将IntStream.iterate限制为特定值

时间:2018-06-05 13:12:12

标签: java java-8 java-stream

我正在生成以下范围:

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

如何将流限制为特定元素值,例如100(不是元素数限制())?

谢谢!

UPDATE 该功能可以是任意的

4 个答案:

答案 0 :(得分:8)

如果您还不能使用Java 9,则可以使用以下三个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);
}

它与Java 9的IntStream.iterate类似,不同之处在于您必须更改正在调用static方法的类(或调整import static语句):

iterate(1, i -> i < 100, i -> i*3).forEach(System.out::println);
1
3
9
27
81

答案 1 :(得分:5)

一种新方法

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

是在Java-9中引入的。因此,从该版本开始,可以执行以下操作:

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

哪会产生1 3 9 27 81

答案 2 :(得分:4)

除了其他答案之外,如果您已经使用,则可以使用Stream#takeWhile作为参数使用Predicate

中测试过
jshell> IntStream.iterate(1, i -> 3*i).takeWhile(i -> i < 100).toArray();
$3 ==> int[5] { 1, 3, 9, 27, 81 }

答案 3 :(得分:0)

IntStream.range(0, N).forEach(this::doSomething);


int[] arr = IntStream.range(start, end).toArray();