Как сгенерировать случайное целое число в заданном диапазоне в Java?
Классический способ с использованием класса Random
Для генерации случайного целого числа в заданном диапазоне в Java используется класс java.util.Random. Основная формула выглядит так:
int randomNumber = min + rand.nextInt(max - min + 1);
Где min — нижняя граница (включительно), max — верхняя граница (включительно). Разберём на примере: нужно получить число от 5 до 15 включительно.
import java.util.Random;
public class RandomExample {
public static void main(String[] args) {
Random rand = new Random();
int min = 5;
int max = 15;
int randomNumber = min + rand.nextInt(max - min + 1);
System.out.println("Случайное число от " + min + " до " + max + ": " + randomNumber);
}
}
Почему это работает?
rand.nextInt(max - min + 1)генерирует число от 0 до (max - min) включительно. В нашем случае max - min = 10, поэтому получаем числа 0..10.- Прибавляя
min(5), мы сдвигаем диапазон: 0+5=5, 10+5=15. Итог: числа от 5 до 15.
Важные нюансы:
- Если
max - min + 1равно нулю или отрицательно, методnextInt()выбросит исключениеIllegalArgumentException. Всегда проверяйте, что max >= min. - Не создавайте новый объект
Randomкаждый раз, когда нужно одно случайное число — это снижает производительность и может привести к повторяющимся значениям (если создавать объекты слишком часто). Лучше создать один экземпляр и переиспользовать его. - Для многопоточных приложений используйте
ThreadLocalRandom(см. альтернативный ответ).
Современный способ (Java 17+)
Начиная с Java 17, в класс RandomGenerator добавлен удобный метод nextInt(int origin, int bound), который генерирует число от origin (включительно) до bound (исключительно). Обратите внимание: верхняя граница не включается! Чтобы получить включительную верхнюю границу, нужно прибавить 1 к bound.
import java.util.random.RandomGenerator;
public class ModernRandomExample {
public static void main(String[] args) {
RandomGenerator generator = RandomGenerator.getDefault();
int min = 5;
int max = 15;
// nextInt(origin, bound) — bound не включается, поэтому max + 1
int randomNumber = generator.nextInt(min, max + 1);
System.out.println("Случайное число: " + randomNumber);
}
}
Этот способ более читаемый и безопасный, так как исключает ошибки с вычислением диапазона. Рекомендую использовать его, если вы работаете с Java 17 или новее.
Полный пример для копирования
import java.util.Random;
import java.util.random.RandomGenerator;
public class CompleteExample {
public static void main(String[] args) {
// Способ 1: классический
Random rand = new Random();
int classicResult = 5 + rand.nextInt(11); // 11 = 15 - 5 + 1
System.out.println("Classic: " + classicResult);
// Способ 2: современный (Java 17+)
RandomGenerator gen = RandomGenerator.getDefault();
int modernResult = gen.nextInt(5, 16); // 16 = 15 + 1
System.out.println("Modern: " + modernResult);
}
}
<<Использование ThreadLocalRandom для многопоточных приложений
Если ваше приложение работает с несколькими потоками, класс Random может стать узким местом из-за синхронизации. В таких случаях лучше использовать java.util.concurrent.ThreadLocalRandom. Он предоставляет локальную копию генератора для каждого потока, что повышает производительность.
import java.util.concurrent.ThreadLocalRandom;
public class ThreadLocalRandomExample {
public static void main(String[] args) {
int min = 5;
int max = 15;
int randomNumber = ThreadLocalRandom.current().nextInt(min, max + 1);
System.out.println("Случайное число: " + randomNumber);
}
}
Преимущества:
- Не нужно создавать экземпляр генератора — метод
current()возвращает генератор для текущего потока. - Работает быстрее в многопоточном окружении.
- Поддерживает метод
nextInt(int origin, int bound)с тем же принципом: origin включительно, bound исключительно.
Этот подход идеален для серверных приложений, веб-сервисов или любой обработки данных в параллельных потоках. Для простых однопоточных программ разница незаметна, но привычка использовать ThreadLocalRandom убережёт вас от проблем в будущем.