如何用 Java8创建无限流

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

例如在 Scala 中:

Iterator.iterate(0)(_ + 2)
27341 次浏览

这里有一个例子:

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(),它为您提供了一个随机整数的无限流。

是的,有一种 放松的方式:

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);

后者在使用中可能更不常见。

您可以通过实现流和使用者来构建自己的 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

爪哇8还有另一种可能的解决方案:

AtomicInteger adder = new AtomicInteger();
IntStream stream = IntStream.generate(() -> adder.getAndAdd(2));

重要提示: 只有当流是连续的时候,才保留数字的顺序。


同样值得注意的是,IntStream.iterate的新版本已经在 爪哇9之后被添加了:

static IntStream iterate​(int seed,
IntPredicate hasNext,
IntUnaryOperator next);
  • 籽- 初始元素;
  • HasNext- 应用于元素的谓词,以确定流何时必须终止;
  • Next- 应用于前一个元素以生成新元素的函数。

例子:

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


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