Простейшим способом получения целого числа в заданном диапазоне можно считать следующий: public static int getRandBetween(int min, int max) { return min + new Random().nextInt(max - min + 1);} Здесь и далее, мы выносим все проверки исходных данных за скобки, предполагая, что минимум всегда меньше максимума, а также величины достаточно далеки от максимального и минимального значения int'а, так что у нас нет проблемы перехода этих границ при проведении арифметических операций.
Использование класса Random
Вообще выше приведено довольно грубое использование класса Random, поскольку оно игнорирует ряд его примечательных возможностей. В первую очередь -- это возможность задать начальное зерно (seed) для последующей генерации чисел. Наличие зерна позволяет генерировать всегда одинаковую последовательность псевдослучайных чисел, что может быть крайне полезно в целях отладки. Например: public class RandExample { static Random random = new Random(0L); public static void main(String[] args) { for (int i = 0; i < 3; i++) { System.out.println(getRandBetween(1, 100)); } } public static int getRandBetween(int min, int max) { return min + random.nextInt(max - min + 1); }} На моей машине каждый перезапуск этой программы выводит в консоль одну и ту же последовательность чисел: 61, 49, 30. Закончив отладку, можно исключить зерно из кода программы. Начиная с версии Java 8 класс Random позволяет получить поток (IntStream) псевдослучайных целых для последующей обработки. Например, следующий код будет выводить в консоль псевдослучайные целые числа до тех пор, пока исполнение программы не будет прервано вручную: random.ints().forEach(System.out::println); Разумеется, на поток можно наложить ограничения. Например: random.ints(10).forEach(System.out::println); выведет в консоль уже всего 10 целых чисел, а random.ints(10, 1, 11).forEach(System.out::println); выведет в консоль 10 целых чисел в диапазоне от 1 до 10-ти, что нам и требовалось изначально. Из примера видно, максимум задаётся, как максимально необходимое число + 1, и в документации отмечено, что передаваемая параметром верхняя граница исключается (exclusive). Аналогично метод doubles() позволяет получить (и ограничить) поток псевдослучайных чисел типа double (DoubleStream).
Многопоточные приложения
Начиная с Java 7 для получения псевдослучайных целых в определённом диапазоне, можно получить отдельный Random для каждого потока: Random safeRandom = ThreadLocalRandom.current(); Так как если использовать один экземпляр Random для нескольких потоков, на них всех будет приходится одно зерно. Это в силу специфики реализации класса Random может приводить к ухудшению производительности. Решением является использование класса ThreadLocalRandom, который наследует Random со всеми его методами, но не имеет указанной проблемы.
Класс Math
Класс Math имеет метод random(), который возвращает случайный double в диапазоне от 0.0 до 1.0. Это значение вполне можно привести к требуемому диапазону целых, например так: public static int getRandBetween(int min, int max) { return min + (int)(Math.random() * ((max - min) + 1));} Однако, следует отметить, что этот метод банально использует nextDouble() отдельного экземпляра Random. И как генератор псевдослучайных чисел ничем особо не интересен. private static final class RandomNumberGeneratorHolder { static final Random randomNumberGenerator = new Random();} public static double random() { return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();}