Как да генерирате произволно число в Java
⚡ Умно обобщение
Случайни числа в Java идват от четири свързани опции на стандартната библиотека, класа Random, Math.random, ThreadLocalRandom и SecureRandom, всяка от които покрива различна комбинация от скорост, безопасност на нишките и криптографска сила за реални приложения.

Случайни числа се появяват навсякъде в Java, от данни от модулни тестове и игри с хвърляне на зарове до жетони за сесия и разбъркани тестета карти. Този урок обяснява как да се генерират случайни числа в Java използване на всяка опция в стандартната библиотека и как да се избере правилната за задачата.
Генериране на случайно число в Java
- Java Стандартната библиотека предлага четири често срещани начина за генериране на случайно число:
java.util.Randomе клас с общо предназначение. Той генерира булеви, 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. За да направите последователността възпроизводима, подайте начален елемент (seed) на конструктора, например new Random(42); едно и също семе винаги произвежда една и съща последователност, което е полезно при тестове и симулации.
Пример: Използване Java Math.random
За да генерирате десет случайни стойности в диапазона от 0.0 до 1.0, извикайте static Math.random метод вътре в контурТова е най-бързият начин да получите произволно двойно число, без да създавате обект генератор:
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 е безопасен за нишки, но бавен при конфликт, защото всяка нишка трябва да се синхронизира върху едно и също вътрешно начално число (seed). 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 защото използва по-силни алгоритми и по-богат начален материал. Запазете го за работа по сигурността и използвайте по-бързите генератори за игри, симулации и тестови данни.
