代码之家  ›  专栏  ›  技术社区  ›  Dmitry Senkovich

将intstream.iterate限制为特定值

  •  4
  • Dmitry Senkovich  · 技术社区  · 6 年前

    我正在生成,比方说,以下范围:

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

    如何将流限制为特定的元素值,例如100(不是使用limit()计算的元素数)?

    谢谢您!

    更新 函数可以是任意的

    4 回复  |  直到 6 年前
        1
  •  9
  •   Holger    6 年前

    如果您还不能使用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
    
        2
  •  5
  •   Anton Balaniuc    6 年前

    新方法

    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

        3
  •  5
  •   Yassin Hajaj    5 年前

    作为其他答案的补充,如果您可以使用 已经有另一种可能 Stream#takeWhile 采取一 Predicate 作为参数。

    在测试

    jshell> IntStream.iterate(1, i -> 3 * i).takeWhile(i -> i < 100).toArray();
    $3 ==> int[5] { 1, 3, 9, 27, 81 }
    
        4
  •  0
  •   surendrapanday    6 年前
    IntStream.range(0, N).forEach(this::doSomething);
    
    
    int[] arr = IntStream.range(start, end).toArray();