0Pricing
Java Academy · Урок

Генерация примитивных потоков

iterate и generate

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

Бесконечным потокам нужны ограничения

iterate и generate создают потенциально бесконечные потоки. Необходимо добавить limit (или предикат), чтобы сделать их конечными.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.iterate(1, n -> n + 1)
            .limit(5)
            .forEach(System.out::println);
    }
}

Итерация с начальным значением

iterate(seed, next) начинается с начального значения и многократно применяет функцию к предыдущему значению.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.iterate(2, n -> n * 2)
            .limit(5)
            .forEach(System.out::println);
    }
}

Итерация с предикатом

Трёхаргументный вариант iterate(seed, hasNext, next) автоматически останавливается, когда предикат принимает значение false, подобно функциональному циклу for.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.iterate(1, n -> n <= 100, n -> n * 3)
            .forEach(System.out::println);
    }
}

Генерация с поставщиком

generate принимает IntSupplier, который независимо создаёт каждый элемент, не зависящий от предыдущего значения.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        IntStream.generate(() -> 7)
            .limit(3)
            .forEach(System.out::println);
    }
}

Генерация случайных чисел

Поставщик для generate может обращаться к источнику случайных значений. Здесь каждый элемент представляет собой независимый результат броска игральной кости.

import java.util.Random;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        Random rnd = new Random(42);
        IntStream.generate(() -> rnd.nextInt(6) + 1)
            .limit(5)
            .forEach(System.out::println);
    }
}

Сравнение iterate и generate

Ключевое различие:

  • iterate: каждое значение выводится из предыдущего (последовательности).
  • generate: каждое значение создаётся независимо (константы, случайные значения).
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int sum = IntStream.iterate(1, n -> n + 1).limit(10).sum();
        System.out.println(sum);
    }
}

Агрегирование сгенерированных потоков

После ограничения сгенерированные потоки поддерживают все обычные агрегатные операции.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        long count = IntStream.iterate(0, n -> n + 2)
            .limit(50)
            .filter(n -> n % 3 == 0)
            .count();
        System.out.println(count);
    }
}

Числа Фибоначчи с iterate в объектном потоке

Для последовательностей, хранящих состояние, таких как последовательность Фибоначчи, используйте Stream.iterate с парой массивов, а затем преобразуйте результат обратно в int.

import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        Stream.iterate(new int[]{0, 1}, p -> new int[]{p[1], p[0] + p[1]})
            .limit(8)
            .mapToInt(p -> p[0])
            .forEach(System.out::println);
    }
}

Создание массива с помощью генератора

Объедините генератор с toArray, чтобы процедурно создать массив примитивных значений.

import java.util.Arrays;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int[] squares = IntStream.iterate(1, n -> n + 1)
            .limit(5)
            .map(n -> n * n)
            .toArray();
        System.out.println(Arrays.toString(squares));
    }
}

Ленивость экономит работу

Потоки являются ленивыми: при использовании limit генерируются только необходимые элементы, даже если источник бесконечен.

import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        int first = IntStream.iterate(10, n -> n + 10)
            .filter(n -> n > 25)
            .findFirst()
            .getAsInt();
        System.out.println(first);
    }
}

Предпочитайте вариант с предикатом

Вариант iterate с предикатом часто понятнее, чем iterate(...).limit(...), поскольку условие остановки находится рядом с логикой генерации.

import java.util.stream.LongStream;

public class Main {
    public static void main(String[] args) {
        long product = LongStream.iterate(1, n -> n <= 5, n -> n + 1)
            .reduce(1, (a, b) -> a * b);
        System.out.println(product);
    }
}

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

Что произойдёт, если вызвать generate без limit, а затем применить терминальную операцию, например forEach?

Итоги

Вы создавали потоки примитивных значений:

  • iterate выводит каждое значение из предыдущего.
  • generate независимо создаёт значения с помощью поставщика.
  • Оба потока бесконечны; ограничивайте их с помощью limit или варианта iterate с предикатом.
  • Благодаря ленивости вычисляются только необходимые элементы.

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

Урок «Генерация примитивных потоков» бесплатный?

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

Чему я научусь в уроке «Генерация примитивных потоков»?

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

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

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

Сколько времени занимает урок «Генерация примитивных потоков»?

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

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

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

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

  1. IntStream и LongStream
  2. Диапазоны и агрегирующие операции
  3. Преобразование объектных потоков и обратно
  4. Генерация примитивных потоков
← Назад к Java Academy