0Pricing
Java Academy · Урок

Бесконечные потоки с iterate и generate

Создавайте бесконечные потоки с помощью Stream.iterate и Stream.generate, а затем останавливайте их с помощью ограничения или take-while.

«Бесконечные потоки с iterate и generate» — бесплатный урок Java Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.

Что такое бесконечные потоки

Потоки Java могут быть бесконечными — они создают элементы по требованию и не имеют конца. Чтобы поток не выполнялся бесконечно, его необходимо завершать ограничивающей операцией (limit, takeWhile, findFirst и т. д.).

Stream.iterate: последовательности с начальным значением

Stream.iterate(seed, f) создаёт бесконечный поток, многократно применяя f к предыдущему значению. Первым элементом является начальное значение.

// Infinite even numbers: 0, 2, 4, 6, 8, ...
Stream.iterate(0, n -> n + 2)
    .limit(10)
    .forEach(System.out::println);

iterate с predicate (Java 9+)

Stream.iterate(seed, predicate, f) добавляет условие остановки — аналогично циклу с условием. Поток останавливается, когда predicate принимает значение false.

// Equivalent to: for (int i = 1; i <= 100; i *= 2)
Stream.iterate(1, n -> n <= 100, n -> n * 2)
    .forEach(System.out::println); // 1 2 4 8 16 32 64

Stream.generate: генератор без состояния

Stream.generate(Supplier) вызывает поставщик для каждого элемента. Поставщик может быть без состояния (случайные числа) или иметь состояние (например, использовать внешний счётчик).

// Infinite random doubles between 0.0 and 1.0:
Stream.generate(Math::random)
    .limit(5)
    .forEach(System.out::println);

Генерация UUID

Используйте generate вместе с UUID::randomUUID, чтобы создать поток уникальных идентификаторов для пакетной генерации ID.

List<String> ids = Stream.generate(() -> UUID.randomUUID().toString())
    .limit(100)
    .collect(Collectors.toList());
System.out.println(ids.size()); // 100

Числа Фибоначчи с iterate

Создавайте числа Фибоначчи, используя состояние, представленное парой значений. Двухаргументный вариант iterate из Java 9 делает это решение элегантным.

Stream.iterate(new long[]{0, 1}, p -> new long[]{p[1], p[0]+p[1]})
    .limit(10)
    .map(p -> p[0])
    .forEach(System.out::println); // 0 1 1 2 3 5 8 13 21 34

takeWhile и dropWhile (Java 9+)

takeWhile(predicate) берёт элементы, пока выполняется predicate, затем останавливается. dropWhile пропускает элементы, пока predicate не даст false, а затем берёт остальные.

// takeWhile stops at the first element where predicate is false:
Stream.iterate(1, n -> n + 1)
    .takeWhile(n -> n < 10)
    .forEach(System.out::println); // 1 2 3 4 5 6 7 8 9

Бесконечные потоки для повторного опроса

Смоделируйте цикл опроса с помощью generate: генерируйте результаты проверки, применяйте takeWhile, пока условие не выполнено, затем возьмите первый успешный результат.

Optional<String> result = Stream.generate(() -> checkJobStatus(jobId))
    .takeWhile(status -> status.equals("PENDING"))
    .findFirst();
// When job completes, takeWhile stops and findFirst gets "DONE"

IntStream.range и rangeClosed

Для конечных последовательностей целых чисел IntStream.range(start, end) и rangeClosed(start, end) эффективнее, чем iterate.

// Sum 1 to 1000:
int sum = IntStream.rangeClosed(1, 1000).sum();
System.out.println(sum); // 500500

LongStream.iterate для последовательностей типа long

Используйте LongStream.iterate для последовательностей типа long, чтобы избежать накладных расходов автоприведения типов у Stream<Long>.

long sumOfPrimes = LongStream.iterate(2, n -> n + 1)
    .filter(n -> isPrime(n))
    .limit(1000)
    .sum();

Бесконечные потоки ленивы

Бесконечные потоки не вычисляют элементы заранее. Каждый элемент создаётся только тогда, когда его запрашивает терминальная операция. Благодаря этой ленивости бесконечные потоки удобны на практике.

Быстрая проверка

Какой механизм остановки необходим при работе с бесконечным потоком?

Итоги

iterate(seed, f) предназначен для последовательностей, а generate(supplier) — для независимого создания элементов. Всегда добавляйте терминальную операцию с досрочным завершением (limit, takeWhile, findFirst). Бесконечные потоки ленивы — они материализуются только по требованию.

Часто задаваемые вопросы

Урок «Бесконечные потоки с iterate и generate» бесплатный?

Да — полный текст урока «Бесконечные потоки с iterate и generate» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.

Чему я научусь в уроке «Бесконечные потоки с iterate и generate»?

Создавайте бесконечные потоки с помощью Stream.iterate и Stream.generate, а затем останавливайте их с помощью ограничения или take-while. Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Бесконечные потоки с iterate и generate»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. flatMap для вложенных коллекций
  2. Параллельные потоки: производительность и подводные камни
  3. Spliterator: разделение для параллельной обработки
  4. Бесконечные потоки с iterate и generate
← Назад к Java Academy