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 razred: java.util.Random otkriva nextInt, nextLong, nextDoublei nextBoolean za uobičajene primitivne tipove.
  • 🧮 Math.random: Math.random vraća double između 0.0 (uključivo) i 1.0 (isključivo) koristeći zajedničku instancu Random.
  • 🎯 Prilagođeni rasponi: Proslijedite granicu nextInt-u ili skalirajte Math.random za generiranje vrijednosti unutar bilo kojeg minimuma i maksimuma.
  • 🧵 Sigurnost niti: ThreadLocalRandom u java.util.concurrent daje svakoj niti vlastiti generator i nadmašuje zajednički Random pod konkurencijom.
  • 🔐 Sigurnost: SecureRandom u java.security generira kriptografski jake vrijednosti za lozinke, tokene i ključeve sesije.
  • ???? Reproducibilnost: Zasijavanje Randoma s fiksnom duljinom čini testove i simulacije determinističkim kroz izvršavanja.

Kako generirati slučajni broj u Java

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.Random je klasa opće namjene. Proizvodi boolean, int, long, float i double vrijednosti putem metoda kao što su nextInt, nextLongi nextDouble.
  • Math.random je statički pomoćnik koji vraća dvostruku vrijednost između 0.0 (uključivo) i 1.0 (isključivo) koristeći dijeljenu Random interno.
  • ThreadLocalRandom in java.util.concurrent daje svakoj niti vlastiti generator, tako da se više niti ne natječu na jednoj instanci.
  • SecureRandom in java.security proizvodi 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.

Pitanja i odgovori

Napravite instancu java.util.Random i pozovite nextInt, nextLong, nextDoubleili nextBoolean. Za brzi zadatak, koristite Math.random koji vraća double između 0.0 i 1.0. Oba pristupa dolaze sa standardnom bibliotekom.

Pozovite random.nextInt(max – min + 1) + min za cijele brojeve ili min + (max – min) * Math.random() za dvostruke brojeve. Formule skaliraju raspon generatora prema vašem ciljnom prozoru i pomiču se za minimalnu vrijednost.

Random je potpuna klasa s metodama za mnoge primitivne tipove i podržava zasijavanje. Math.random je statički pomoćnik koji vraća double između 0.0 i 1.0. Interno, Math.random poziva jednu zajedničku instancu Random.

Da, ali istovremeni pozivi se natječu za isti interni seed, što usporava kod s puno niti. Koristite ThreadLocalRandom.current() iz java.util.concurrent kako biste svakoj niti dali vlastiti generator i uklonili tu natjecateljsku borbu.

Proslijedite fiksnu duljinu konstruktoru Random, na primjer new Random(42), ili pozovite setSeed(42). Generator će proizvesti isti niz pri svakom pokretanju, što je bitno za ponovljive testove i simulacije.

Koristite SecureRandom kad god vrijednost mora biti otporna na predviđanje, kao što su lozinke, tokeni sesije, vrijednosti soli, jednokratni kodovi i kriptografski ključevi. Plain Random je brz, ali predvidljiv, pa nije siguran za sigurnosne radove.

Okviri za strojno učenje koriste pseudo-slučajne generatore za inicijalizaciju težina, miješanje podataka za učenje i dijeljenje skupova za validaciju. Fiksiranje početne vrijednosti čini eksperimente ponovljivima tako da timovi mogu pouzdano uspoređivati ​​​​izvođenja modela i otklanjati pogreške u rezultatima.

Da. GitHub Copilot scaffoldira isječke Random, ThreadLocalRandom i SecureRandom, odgovarajuće formule za skaliranje raspona i JUnit ispitivanja. RevPregledajte svaki prijedlog kako biste potvrdili da odabrana klasa odgovara slučaju upotrebe, posebno za sigurnosno osjetljiv kod.

Sažmite ovu objavu uz: