Как создать бесконечный поток с Java 8


есть ли простой способ создать бесконечный поток с помощью java-8 без внешних библиотек?

например в Scala:

Iterator.iterate(0)(_ + 2)
4 60

4 ответа:

Да, есть такое легко путь:

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

С usecase:

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

который печатает вне 0 до 198 увеличивая в шагах 2.

общий метод:

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

последняя может быть более необычным, в использовании.

вот пример:

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() что дает вам бесконечный поток случайных чисел.

есть еще одно возможное решение в Java 8:

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

важно: порядок чисел сохраняется только в том случае, если поток является последовательным.


также стоит отметить, что новая версия IntStream.iterate был добавлен с Java 9:

static IntStream iterate​(int seed,
                         IntPredicate hasNext,
                         IntUnaryOperator next);
  • seed - начальный элемент;
  • hasNext - предикат для применения к элементам to определите, когда поток должен завершиться;
  • далее - функция, применяемая к предыдущему элементу для создания нового элемента.

примеры:

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

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

вы можете построить свой собственный 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