题 如何使用Java 8创建无限流


有没有一种简单的方法来创建无限流使用  没有外部库?

例如在Scala中:

Iterator.iterate(0)(_ + 2)

60
2018-03-18 15:16


起源




答案:


是的,有一个 简单 办法:

IntStream.iterate(0, i -> i + 2);

作为用例:

IntStream.iterate(0, i -> i + 2)
         .limit(100)
         .forEach(System.out::println);

其中打印出0到198,步长为2。

通用方法是:

Stream.iterate(T seed, UnaryOperator<T> f);

后者在使用中可能更为罕见。


88
2018-03-18 15:40



很好,我没有在API文档中看到这一点。 - Jesper
+1,但值得一提的是 IntStream.generate 可以用的时候 IntStream.iterate 不适合,例如斐波纳契数列。 - Daniel Lubarov
怎么样 IntStream.iterate 不适合 Fibnoacci? - Asif Mushtaq


这是一个例子:

PrimitiveIterator.OfInt it = new PrimitiveIterator.OfInt() {
    private int value = 0;

    @Override
    public int nextInt() {
        return value++;
    }

    @Override
    public boolean hasNext() {
        return true;
    }
};

Spliterator.OfInt spliterator = Spliterators.spliteratorUnknownSize(it,
    Spliterator.DISTINCT | Spliterator.IMMUTABLE |
    Spliterator.ORDERED | Spliterator.SORTED);

IntStream stream = StreamSupport.intStream(spliterator, false);

正如你所看到的那样,它有点冗长。要打印此流的前10个元素:

stream.limit(10).forEach(System.out::println);

您可以像在Scala示例中那样转换元素:

IntStream plusTwoStream = stream.map(n -> n + 2);

请注意,有内置的无限流,如 java.util.Random.ints() 它为您提供无限的随机整数流。


6
2018-03-18 15:34



鉴于你的 PrimitiveIterator.OfInt it, 一个简单的 IntStream.generate(it::next) 也行得通。所以它甚至根本不必是迭代器,例如 IntStream.generate(new AtomicInteger()::incrementAndGet) 也将提供这样一个自然数字序列。 - Holger
是的,显然我的解决方案比必要的更冗长,并且有多种方法可以做到这一点。 - Jesper
不知道 java.util.Random.ints(),+ 1 - Markus Weninger


还有另一种可能的解决方案 Java 8

AtomicInteger adder = new AtomicInteger();

IntStream.generate(() -> adder.getAndAdd(2));

有一个例外:仅当流是顺序的时才能正常工作。

值得注意的是,新版本的 IntStream.iterate 自那时起就被添加了 Java 9

static IntStream iterate​(int seed,
                         IntPredicate hasNext,
                         IntUnaryOperator next);

第二个参数是一个谓词,用于应用于元素以确定流必须终止的时间:

IntStream.iterate(0, i -> i >= 0, i -> i + 2);

IntStream.iterate(0, i -> i < 10, i -> i + 2).forEach(System.out::println);

1
2018-06-26 09:20





您可以通过实现流和使用者来构建自己的InfiniteStream并组合它们,并且可能需要排队以将数据排队为:

public class InfiniteStream<T> implements Consumer<T>, Stream<T> {
private final Stream<T> stream;
private final Queueing q;
...
public InfiniteStream(int length) {
    this.q = new Queueing(this.length);
    this.stream = Stream.generate(q);
    ...
}
    //implement stream methods
    //implement accept
}

在这里查看完整代码 https://gist.github.com/bassemZohdy/e5fdd56de44cea3cd8ff


0
2017-09-21 17:23