Avatar ·

Как сгенерировать случайное целое число в заданном диапазоне в Java?

Всем привет! Я только начал изучать Java и столкнулся с задачей, которая кажется простой, но вызывает у меня затруднения. Мне нужно сгенерировать случайное целое число в определённом диапазоне, например, от 1 до 10 (включительно). Я знаю, что в Java есть класс `Random`, и я пробовал использовать метод `nextInt()`, но он возвращает числа от 0 до какого-то предела. Вот что я написал: ```java import java.util.Random; public class TestRandom { public static void main(String[] args) { Random rand = new Random(); int randomNumber = rand.nextInt(10); // Получаю числа от 0 до 9 System.out.println(randomNumber); } } ``` Проблема в том, что мне нужно, чтобы диапазон начинался не с 0, а с произвольного числа, например, с 5 до 15. Я пробовал прибавлять константу, но тогда верхняя граница тоже сдвигается, и я не уверен, что делаю это правильно. Кроме того, я слышал, что в Java 17 появился новый способ генерации случайных чисел, но не знаю, как им пользоваться. Подскажите, пожалуйста, как правильно решить эту задачу? Желательно с примером кода, чтобы я мог сразу его скопировать и использовать. Заранее спасибо! <<>>

Классический способ с использованием класса 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 убережёт вас от проблем в будущем.