Як згенерувати випадкове число в 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 для симуляції. Два шаблони охоплюють майже кожен випадок.
Випадкове ціле число від мінімуму до максимуму (включно):
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 оскільки він використовує потужніші алгоритми та багатший початковий матеріал. Зарезервуйте його для роботи з безпекою та використовуйте швидші генератори для ігор, симуляцій та тестових даних.

