Kako generirati slučajni broj u Java
⚡ Pametni sažetak
Slučajni brojevi u Java dolaze iz četiri povezane opcije standardne biblioteke, klase Random, Math.random, ThreadLocalRandom i SecureRandom, od kojih svaka pokriva različitu kombinaciju brzine, sigurnosti niti i kriptografske snage za stvarne aplikacije.
Slučajni brojevi se pojavljuju svugdje u Java, od podataka jediničnih testova i igara s bacanjem kockica do žetona sesije i promiješanih špilova. Ovaj vodič objašnjava kako generirati slučajne brojeve u Java korištenje svake opcije u standardnoj biblioteci i kako odabrati pravu za posao.
Generiraj slučajni broj u Java
The Java Standardna biblioteka nudi četiri uobičajena načina generiranja slučajnog broja:
java.util.Randomje klasa opće namjene. Proizvodi boolean, int, long, float i double vrijednosti putem metoda kao što sunextInt,nextLonginextDouble.Math.randomje statički pomoćnik koji vraća dvostruku vrijednost između 0.0 (uključivo) i 1.0 (isključivo) koristeći dijeljenuRandominterno.ThreadLocalRandominjava.util.concurrentdaje svakoj niti vlastiti generator, tako da se više niti ne natječu na jednoj instanci.SecureRandominjava.securityproizvodi kriptografski jake pseudo-slučajne brojeve za lozinke, identifikatore sesija i ključeve.
U donjim odjeljcima prikazano je kako generirati deset slučajnih brojeva sa svakim pristupom.
Primjer: Generirajte slučajni broj pomoću Java Slučajni razred
Prvi primjer koristi java.util.Random za dobivanje deset cijelih brojeva u rasponu od 0 do 99 uključivo:
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); } } }
Izlaz:
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
Primjerak Random stvara se kao objGenerator, nextInt(int bound) metoda vraća vrijednost između 0 (uključivo) i zadane granice (isključivo), dakle nextInt(100) daje vrijednosti od 0 do 99. Da bi niz bio reproducibilan, konstruktoru se proslijedi sjeme, na primjer new Random(42); isto sjeme uvijek proizvodi isti niz, što je korisno u testovima i simulacijama.
Primjer: korištenje Java Math.random
Za generiranje deset slučajnih vrijednosti u rasponu od 0.0 do 1.0, pozovite static Math.random metoda unutar petljaOvo je najbrži način za dobivanje slučajnog dvostrukog broja bez stvaranja objekta generatora:
public class DemoRandom { public static void main(String[] args) { for (int xCount = 0; xCount < 10; xCount++) { System.out.println(Math.random()); } } }
Izlaz:
0.46518450373334297 0.14859851177803485 0.5628391820492477 0.6323378498048606 0.1740198445692248 0.9140544122258946 0.9167350036262347 0.49251219841030147 0.7426056725722353 0.2039418871298877
Ispod haube, Math.random stvara jednu statiku Random pri prvoj upotrebi i pozivima nextDouble na njemu. Taj jedan dijeljeni generator je u redu za demonstracije, ali postaje usko grlo pod velikim višenitnim opterećenjem, što se obrađuje u sljedećim odjeljcima.
Generiranje slučajnog broja u prilagođenom rasponu
Pravi programi obično trebaju slučajnu vrijednost unutar određenog raspona, kao što je cijeli broj između 1 i 6 za bacanje kocke ili dvostruki broj između 10.0 i 20.0 za simulaciju. Dva obrasca pokrivaju gotovo svaki slučaj.
Slučajni cijeli broj između min i max (uključivo):
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); } }
Slučajni dvostruki broj između min i max:
double min = 10.0; double max = 20.0; double value = min + (max - min) * Math.random(); System.out.println("Value : " + value);
Oba obrasca rade tako da uzimaju vrijednost iz izvornog raspona generatora, skaliraju je na širinu ciljnog raspona i pomiču je prema gore za minimum. Ako ste na Java 8 ili noviji, isti rezultat je dostupan i putem novije verzije ints, longsi doubles metode streama uključene Random, Na primjer rnd.ints(10, 1, 7).forEach(System.out::println) za deset bacanja kocke.
ThreadLocalRandom za višenitne Code
Jedan dijeljeni Random je siguran za korištenje u nitovima, ali spor pod konkurencijom jer se svaka nit mora sinkronizirati na istom internom sjemenu. ThreadLocalRandom, dodano u Java 7 i živim u java.util.concurrent, daje svakoj niti vlastiti generator tako da nema sukoba zaključavanja.
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); } }
Koristiti ThreadLocalRandom.current() unutar radnih niti, paralelnih tokova i bilo kojeg istodobnog zadatka. Imajte na umu da setSeed baca UnsupportedOperationException, tako da se zasijavanje radi reproducibilnosti ne podržava; ako vam je potrebno fiksno zasijavanje, držite se običnog Random.
SecureRandom za sigurnosno osjetljiv slučajni odabir Numbers
Slučajevi Random i ThreadLocalRandom nisu kriptografski sigurni. S obzirom na nekoliko izlaznih uzoraka, napadač može rekonstruirati unutarnje stanje i predvidjeti buduće vrijednosti. Za lozinke, tokene sesije, vrijednosti soli i kriptografske ključeve koristite java.security.SecureRandom Umjesto toga. Crpi početni materijal iz entropijskog bazena operacijskog sustava i proizvodi vrijednosti koje se opiru predviđanju.
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 je sporiji od Random jer koristi jače algoritme i bogatiji početni materijal. Rezervirajte ga za sigurnosne poslove, a brže generatore koristite za igre, simulacije i testne podatke.

