Как сгенерировать случайное число в Java
⚡ Умное резюме
Случайные числа в Java Они берутся из четырех связанных вариантов стандартной библиотеки: класса Random, Math.random, ThreadLocalRandom и SecureRandom, каждый из которых обеспечивает различное сочетание скорости, потокобезопасности и криптографической стойкости для реальных приложений.

Случайные числа встречаются повсюду. JavaОт данных для модульного тестирования и игр с бросанием кубиков до токенов сессии и перемешанных колод. В этом руководстве объясняется, как генерировать случайные числа. Java Использование всех опций стандартной библиотеки и выбор подходящей для конкретной задачи.
Генерация случайного числа в Java
Java Стандартная библиотека предлагает четыре распространенных способа генерации случайного числа:
java.util.RandomЭто универсальный класс. Он возвращает значения типов boolean, int, long, float и double с помощью таких методов, как...nextInt,nextLongиnextDouble.Math.randomЭто статическая вспомогательная функция, которая возвращает значение типа double от 0.0 (включительно) до 1.0 (исключительно), используя разделяемую переменную.Randomвнутренне.ThreadLocalRandominjava.util.concurrentЭто позволяет каждому потоку иметь собственный генератор, благодаря чему несколько потоков не конкурируют за один экземпляр.SecureRandominjava.securityгенерирует криптографически стойкие псевдослучайные числа для паролей, идентификаторов сессий и ключей.
В разделах ниже показано, как сгенерировать десять случайных чисел каждым из способов.
Пример: генерация случайного числа с помощью Java Случайный класс
В первом примере используется java.util.Random получить десять целых чисел в диапазоне от 0 до 99 включительно:
import java.util.Random; public class RandomNumbers { public static void main(String[] args) { Random objGenerator = new Random(); for (int iCount = 0; iCount < 10; iCount++) { int randomNumber = objGenerator.nextInt(100); System.out.println("Random No : " + randomNumber); } } }
Выход:
Random No : 17 Random No : 57 Random No : 73 Random No : 48 Random No : 68 Random No : 86 Random No : 34 Random No : 97 Random No : 73 Random No : 18
Экземпляр Random создается как objGenerator, nextInt(int bound) Метод возвращает значение от 0 (включительно) до заданного предела (исключительно), поэтому nextInt(100) возвращает значения от 0 до 99. Для обеспечения воспроизводимости последовательности передайте в конструктор начальное значение, например: new Random(42)Использование одного и того же начального значения всегда приводит к одной и той же последовательности, что полезно в тестах и моделировании.
Пример: Использование Java Math.random
Для генерации десяти случайных значений в диапазоне от 0.0 до 1.0 вызовите статическую функцию. Math.random метод внутри поискаЭто самый быстрый способ получить случайное число типа double без создания объекта-генератора:
public class DemoRandom { public static void main(String[] args) { for (int xCount = 0; xCount < 10; xCount++) { System.out.println(Math.random()); } } }
Выход:
0.46518450373334297 0.14859851177803485 0.5628391820492477 0.6323378498048606 0.1740198445692248 0.9140544122258946 0.9167350036262347 0.49251219841030147 0.7426056725722353 0.2039418871298877
Под капотом, Math.random создает один статический объект Random при первом использовании и звонках nextDouble Это касается данного случая. Этот единственный общий генератор подходит для демонстраций, но становится узким местом при высокой многопоточной нагрузке, что будет рассмотрено в следующих разделах.
Сгенерировать случайное число в заданном диапазоне
В реальных программах обычно требуется случайное значение в определенном диапазоне, например, целое число от 1 до 6 для броска игральной кости или число с плавающей запятой от 10.0 до 20.0 для моделирования. Два варианта подходят практически для всех случаев.
Случайное целое число в диапазоне от min до max (включительно):
import java.util.Random; public class RangeDemo { public static void main(String[] args) { Random rnd = new Random(); int min = 1; int max = 6; // nextInt(max - min + 1) returns 0..(max-min), then shift by min int dice = rnd.nextInt(max - min + 1) + min; System.out.println("Dice roll : " + dice); } }
Случайное число с плавающей запятой в диапазоне от минимального до максимального значения:
double min = 10.0; double max = 20.0; double value = min + (max - min) * Math.random(); System.out.println("Value : " + value);
Оба алгоритма работают следующим образом: берут значение из исходного диапазона генератора, масштабируют его до ширины целевого диапазона и сдвигают вверх на минимальное значение. Если вы находитесь на Java В версиях 8 и более поздних можно добиться того же результата и в более новых версиях. ints, longs и doubles потоковые методы на Random, например rnd.ints(10, 1, 7).forEach(System.out::println) за десять бросков кубиков.
ThreadLocalRandom для многопоточности Code
Единый общий Random Является потокобезопасным, но медленным при конкуренции за ресурсы, поскольку каждый поток должен синхронизироваться с одним и тем же внутренним начальным значением. ThreadLocalRandom, добавлено в Java 7 и проживает в java.util.concurrent, это дает каждому потоку свой собственный генератор, поэтому конфликтов блокировок не возникает.
import java.util.concurrent.ThreadLocalRandom; public class ThreadLocalDemo { public static void main(String[] args) { // random int in [1, 100] int i = ThreadLocalRandom.current().nextInt(1, 101); // random long in [1000, 5000] long l = ThreadLocalRandom.current().nextLong(1000L, 5001L); // random double in [0.0, 1.0) double d = ThreadLocalRandom.current().nextDouble(); System.out.println(i + " " + l + " " + d); } }
Используйте ThreadLocalRandom.current() внутри рабочих потоков, параллельных потоков и любых параллельно выполняемых задач. Обратите внимание, что setSeed бросает UnsupportedOperationExceptionТаким образом, использование генератора случайных чисел для обеспечения воспроизводимости результатов не поддерживается; если вам нужен фиксированный генератор случайных чисел, используйте обычный генератор случайных чисел. Random.
SecureRandom для генерации случайных чисел, имеющих важное значение для безопасности. Numbers
Экземпляры Random и ThreadLocalRandom Они не являются криптографически защищенными. Имея несколько примеров выходных данных, злоумышленник может восстановить внутреннее состояние и предсказать будущие значения. Для паролей, токенов сессии, значений соли и криптографических ключей используйте java.security.SecureRandom Вместо этого он берет исходный материал из пула энтропии операционной системы и выдает значения, которые не поддаются прогнозированию.
import java.security.SecureRandom; public class SecureDemo { public static void main(String[] args) { SecureRandom secure = new SecureRandom(); byte[] token = new byte[16]; secure.nextBytes(token); // 128-bit random token int otp = secure.nextInt(1_000_000); // 6-digit one-time code System.out.println("OTP : " + String.format("%06d", otp)); } }
SecureRandom медленнее, чем Random Потому что он использует более мощные алгоритмы и более богатый исходный материал. Используйте его для задач обеспечения безопасности, а более быстрые генераторы — для игр, симуляций и тестовых данных.
