Как создать бесконечный поток с Java 8
есть ли простой способ создать бесконечный поток с помощью java-8 без внешних библиотек?
например в Scala:
Iterator.iterate(0)(_ + 2)
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