NextInt: примеры (JAVA)
nextInt(int bound): intОписание метода nextInt в Java
Метод nextInt предоставляет получение псевдослучайного целого числа и встречается в нескольких реализациях генераторов случайных чисел в Java: java.util.Random, java.security.SecureRandom, java.util.SplittableRandom, java.util.concurrent.ThreadLocalRandom и в API RandomGenerator (Java 17+). Поведение зависит от перегрузки:
- nextInt() - возвращает случайное значение типа
intв полном диапазоне 32-битных знаковых целых: от Integer.MIN_VALUE до Integer.MAX_VALUE включительно. - nextInt(int bound) - возвращает случайное целое в диапазоне [0, bound), то есть 0 включительно и bound исключительно. Параметр
boundдолжен быть больше 0, иначе выбрасываетсяIllegalArgumentException. Распределение равномерное по всем возможным значениям при корректной реализации генератора. - В некоторых реализациях (например,
ThreadLocalRandomиSplittableRandom) есть перегрузка nextInt(int origin, int bound), возвращающая значение в диапазоне [origin, bound). Требование:origin < bound, иначе выбрасываетсяIllegalArgumentException.
Возвращаемые значения: целое число int. При использовании без аргумента возможны любые 32-битные значения. При использовании с ограничением - значения в указанном полуоткрытом диапазоне.
Особенности и заметки:
- Алгоритм генерации у
Randomопределён реализацией в JDK и использует линейный конгруэнтный генератор. Он не криптографически стойкий. SecureRandomиспользует криптографически стойкий источник, но может быть медленнее.ThreadLocalRandomудобен в многопоточных средах, снижая конкуренцию на общем состоянии.- Нельзя предполагать порядок или равномерность между разными реализациями генераторов, если не контролируется конкретная реализация/семя.
Короткие примеры использования
Ниже приведены простые примеры кода со nextInt и возможными результатами. Результаты могут отличаться между версиями Java и запусками, если не задано семя.
1) Полный диапазон
java.util.Random rnd = new java.util.Random(42L);
int x = rnd.nextInt();
System.out.println(x);
Пример вывода: -1170105035
2) Диапазон от 0 до bound-1
java.util.Random rnd = new java.util.Random(42L);
int a = rnd.nextInt(10);
System.out.println(a);
Пример вывода: 5
3) Диапазон с origin и bound (ThreadLocalRandom)
int b = java.util.concurrent.ThreadLocalRandom.current().nextInt(5, 15);
System.out.println(b);
Пример вывода: 12
4) SecureRandom для криптографических нужд
java.security.SecureRandom sr = new java.security.SecureRandom();
int s = sr.nextInt(100);
System.out.println(s);
Пример вывода: 73
Похожие методы в Java и их особенности
- ThreadLocalRandom.nextInt - подходит для многопоточных программ, уменьшает блокировки и даёт лучшую производительность при параллельном доступе.
- SplittableRandom.nextInt - эффективен для параллельных алгоритмов и потоков, поддерживает детерминированное разбиение генератора на независимые копии.
- SecureRandom.nextInt - обеспечивает криптографическую стойкость, рекомендуется для генерации ключей, токенов и секретных кодов; медленнее, чем обычный Random.
- Random.ints / ThreadLocalRandom.ints - возвращают поток (Stream) случайных чисел с опциями размера и диапазона; удобны для потоковой обработки и генерации батчей.
- RandomGenerator (Java 17+) - унифицированный интерфейс и набор реализаций (включая быстрое и качественное PRNG), предпочтителен при необходимости гибкого выбора алгоритма.
Аналоги в других языках и отличия
Краткие примеры аналогов и ключевые различия по языкам.
- JavaScript
// Math.random возвращает double в [0,1)
const n = Math.floor(Math.random() * 10);
console.log(n);
Пример вывода: 3
Для криптостойкости - crypto.getRandomValues, возвращает бинарные данные.
import random
print(random.randint(0, 9)) # включает обе границы
print(random.randrange(0, 10)) # 0..9
Пример вывода: 7 2
Для криптографии - модуль secrets (например, secrets.randbelow).
echo rand(0, 9); // включает обе границы
echo random_int(0, 9); // криптостойкий
Пример вывода: 4
var r = new System.Random(42);
Console.WriteLine(r.Next()); // 0..Int32.MaxValue-1
Console.WriteLine(r.Next(10)); // 0..9
Пример вывода: 1185267 5
Для криптографии - System.Security.Cryptography.RandomNumberGenerator.
import (
"fmt"
"math/rand"
)
fmt.Println(rand.Intn(10)) // 0..9
Пример вывода: 6
Для криптографии - crypto/rand, работа с байтами.
math.randomseed(42)
print(math.random(0, 9))
Пример вывода: 8
val r = kotlin.random.Random(42)
println(r.nextInt())
println(r.nextInt(0, 10))
Пример вывода: -1170105035 5
Kotlin использует собственный API, но на JVM может делегировать java.util.Random. Есть версии для JavaScript и Native.
-- PostgreSQL
SELECT floor(random() * 10)::int AS n; -- 0..9
-- MySQL
SELECT FLOOR(RAND() * 10) AS n;
Пример вывода: 2
Типичные ошибки при использовании nextInt
- Передача нулевого или отрицательного bound
new java.util.Random().nextInt(0);
Выброс: java.lang.IllegalArgumentException: bound must be positive
int v = new java.util.Random().nextInt(10); // возвращается 0..9
if (v == 10) System.out.println("возможно");
Никогда не будет 10; распространённая ошибка - off-by-one.
// НЕКОРРЕКТНО для секретов
int token = new java.util.Random().nextInt(1_000_000);
Риск предсказуемости; следует использовать SecureRandom или платформенные крипто-API.
for (int i=0;i<5;i++){
java.util.Random r = new java.util.Random();
System.out.println(r.nextInt(100));
}
Пример вывода: часто повторяющиеся или схожие числа при быстром создании, так как сид берётся по времени.
// Пытаются взять остаток: может появиться смещение если источник не равномерно делится
int n = new java.util.Random().nextInt() % 10;
Результат может быть отрицательным и менее равномерным; рекомендуется nextInt(10).
Изменения и эволюция API
- В ранних версиях JDK существовал только
java.util.Random. Начиная с Java 7–8 появились удобства: поточные методыints, а в Java 8 -ThreadLocalRandomв JDK 7 и расширения в 8. - В Java 17 представлен API
RandomGeneratorи набор современных реализаций PRNG (JEP 356 и сопутствующие изменения). Это даёт выбор между высокопроизводительными и качественными генераторами вместо единственного LCG изRandom. - Сам метод
Random.nextIntсохраняет совместимость, но при выборе реализации следует учитывать новые классы для улучшения качества или производительности.
Расширенные и редкие сценарии использования
1) Генерация случайного числа в диапазоне [min, max] включительно
int min = -5, max = 7;
int v = java.util.concurrent.ThreadLocalRandom.current().nextInt(min, max + 1);
System.out.println(v);
Пример вывода: 3
Пояснение: ThreadLocalRandom поддерживает origin и bound; для включения верхней границы выполняется прибавление 1.
2) Перестановка массива (Fisher-Yates) с использованием nextInt
int[] a = {1,2,3,4,5};
java.util.Random rnd = new java.util.Random();
for (int i = a.length - 1; i > 0; i--) {
int j = rnd.nextInt(i + 1); // 0..i
int t = a[i]; a[i] = a[j]; a[j] = t;
}
System.out.println(java.util.Arrays.toString(a));
Пример вывода: [3, 5, 1, 4, 2]
Пояснение: корректное использование nextInt(i+1) даёт равновероятную перестановку.
3) Генерация случайного long с использованием nextInt
// Составление long из двух int
java.util.Random r = new java.util.Random();
long high = ((long) r.nextInt()) << 32;
long low = ((long) r.nextInt()) & 0xffffffffL;
long combined = high | low;
System.out.println(combined);
Пример вывода: -4123456789012345678
Пояснение: если требуется случайный 64-битный набор битов и нет nextLong(), можно комбинировать два nextInt().
4) Использование потоков случайных чисел
java.util.Random rnd = new java.util.Random(1L);
rnd.ints(5, 0, 100).forEach(System.out::println); // 5 чисел 0..99
Пример вывода: XX YY ZZ ... (примерные значения)
Пояснение: метод ints возвращает IntStream, удобный для функциональной обработки и параллельной генерации.
5) Параллельная генерация без блокировок
java.util.stream.IntStream.range(0, 4)
.parallel()
.map(i -> java.util.concurrent.ThreadLocalRandom.current().nextInt(100))
.forEach(System.out::println);
Пример вывода: 12 87 3 44
Пояснение: ThreadLocalRandom уменьшает конкуренцию между потоками при массовой генерации.
6) Репродуцируемые тесты с фиксированным seed
java.util.Random r1 = new java.util.Random(123);
java.util.Random r2 = new java.util.Random(123);
System.out.println(r1.nextInt());
System.out.println(r2.nextInt());
Пример вывода: -1155484576 -1155484576
Пояснение: одинаковое начальное значение даёт одинаковую последовательность, что удобно для модульного тестирования.
7) Комбинация для ограничения смещения (избегание %)
// Правильно: равномерное значение 0..n-1
int n = 10;
int x = java.util.concurrent.ThreadLocalRandom.current().nextInt(n);
System.out.println(x);
Пример вывода: 6
Пояснение: использование встроенной перегрузки предотвращает ошибки с модульной операцией и отрицательными значениями.