Cum se generează un număr aleatoriu în Java

⚡ Rezumat inteligent

Numere aleatorii în Java provin din patru opțiuni standard ale bibliotecii, clasa Random, Math.random, ThreadLocalRandom și SecureRandom, fiecare acoperind un amestec diferit de viteză, siguranța firelor de execuție și putere criptografică pentru aplicații reale.

  • 🎲 Clasă aleatorie: java.util.Random expune nextInt, nextLong, nextDoubleși nextBoolean pentru tipuri primitive comune.
  • 🧮 Matematică.aleatoriu: Math.random returnează o valoare double între 0.0 inclusiv și 1.0 exclusiv folosind o instanță Random partajată.
  • 🎯 Intervale personalizate: Transmite o limită către nextInt sau scalează Math.random pentru a genera valori în limita oricărui minim și maxim.
  • 🧵 Siguranța filetului: ThreadLocalRandom din java.util.concurrent oferă fiecărui fir de execuție propriul generator și depășește performanța unui Random partajat în condiții de contenție.
  • 🔐 De securitate: SecureRandom din java.security produce valori criptografic puternice pentru parole, token-uri și chei de sesiune.
  • ???? Reproductibilitate: Semănarea unei valori aleatorii cu o valoare long fixă ​​face ca testele și simulările să fie deterministe în diferite runde.

Cum se generează un număr aleatoriu în Java

Numerele aleatorii apar peste tot în Java, de la date de testare unitară și jocuri cu zaruri la jetoane de sesiune și pachete de cărți amestecate. Acest tutorial explică cum se generează numere aleatorii în Java utilizarea fiecărei opțiuni din biblioteca standard și cum să o alegeți pe cea potrivită pentru sarcină.

Generați un număr aleatoriu în Java

Java O bibliotecă standard oferă patru metode comune de generare a unui număr aleatoriu:

  • java.util.Random este clasa de uz general. Produce valori booleene, int, long, float și double prin metode precum nextInt, nextLong și nextDouble.
  • Math.random este un helper static care returnează o valoare double între 0.0 (inclusiv) și 1.0 (exclusiv) folosind o valoare partajată Random intern.
  • ThreadLocalRandom in java.util.concurrent oferă fiecărui fir de execuție propriul generator, astfel încât mai multe fire de execuție să nu concureze pe o singură instanță.
  • SecureRandom in java.security produce numere pseudo-aleatoare criptografic puternice pentru parole, identificatori de sesiune și chei.

Secțiunile de mai jos arată cum se generează zece numere aleatorii cu fiecare abordare.

Exemplu: Generați un număr aleatoriu folosind Java Clasa aleatorie

Primul exemplu folosește java.util.Random pentru a genera zece numere întregi în intervalul de la 0 la 99 inclusiv:

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);
        }
    }
}

ieșire:

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

Un exemplu de Random este creat ca objGenerator. nextInt(int bound) Metoda returnează o valoare între 0 (inclusiv) și limita furnizată (exclusivă), deci nextInt(100) produce valori de la 0 la 99. Pentru a face secvența reproductibilă, transmiteți o valoare inițială constructorului, de exemplu new Random(42)aceeași sămânță produce întotdeauna aceeași secvență, ceea ce este util în teste și simulări.

Exemplu: Folosind Java Matematică aleatorie

Pentru a genera zece valori aleatorii în intervalul 0.0 - 1.0, apelați metoda statică Math.random metodă în interiorul unei buclăAceasta este cea mai rapidă metodă de a obține un double aleatoriu fără a crea un obiect generator:

public class DemoRandom {
    public static void main(String[] args) {
        for (int xCount = 0; xCount < 10; xCount++) {
            System.out.println(Math.random());
        }
    }
}

ieșire:

0.46518450373334297
0.14859851177803485
0.5628391820492477
0.6323378498048606
0.1740198445692248
0.9140544122258946
0.9167350036262347
0.49251219841030147
0.7426056725722353
0.2039418871298877

Sub capotă, Math.random creează o singură statică Random la prima utilizare și la apeluri nextDouble pe el. Acel generator unic partajat este potrivit pentru demonstrații, dar devine un blocaj sub încărcarea multithreaded puternică, aspect abordat în următoarele secțiuni.

Generați un număr aleatoriu într-un interval personalizat

Programele reale au nevoie de obicei de o valoare aleatorie într-un interval specific, cum ar fi un număr întreg între 1 și 6 pentru o aruncare cu zarul sau un rezultat dublu între 10.0 și 20.0 pentru o simulare. Două modele acoperă aproape fiecare caz.

Număr întreg aleatoriu între min și max (inclusiv):

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);
    }
}

Dublu aleatoriu între min și max:

double min = 10.0;
double max = 20.0;
double value = min + (max - min) * Math.random();
System.out.println("Value : " + value);

Ambele modele funcționează prin preluarea unei valori din intervalul nativ al generatorului, scalarea acesteia la lățimea intervalului țintă și deplasarea acesteia în sus cu minimul. Dacă sunteți activat Java 8 sau o versiune ulterioară, același rezultat este disponibil prin intermediul versiunii mai noi ints, longs și doubles metode de flux activate Random, De exemplu, rnd.ints(10, 1, 7).forEach(System.out::println) pentru zece aruncări cu zarurile.

ThreadLocalRandom pentru fire multiple Code

Un singur partajat Random este sigur pentru thread-uri, dar lent în condiții de contenție, deoarece fiecare thread trebuie să se sincronizeze pe aceeași semință internă. ThreadLocalRandom, adăugat în Java 7 și locuind în java.util.concurrent, oferă fiecărui fir de execuție propriul generator, astfel încât să nu existe conflicte de blocare.

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);
    }
}

Utilizare ThreadLocalRandom.current() în interiorul firelor de execuție, fluxurilor paralele și oricărei sarcini concurente. Rețineți că setSeed aruncă UnsupportedOperationException, deci însămânțarea pentru reproductibilitate nu este acceptată; dacă aveți nevoie de o sămânță fixă, rămâneți la cea simplă Random.

SecureRandom pentru informații aleatorii sensibile la securitate Numbers

Exemple de Random și ThreadLocalRandom nu sunt securizate criptografic. Având la dispoziție câteva mostre de ieșire, un atacator poate reconstrui starea internă și poate prezice valori viitoare. Pentru parole, token-uri de sesiune, valori salt și chei criptografice, utilizați java.security.SecureRandom în schimb. Extrage material de bază din entropia sistemului de operare și produce valori care rezistă predicției.

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 este mai lent decât Random deoarece folosește algoritmi mai puternici și un material inițial mai bogat. Rezervați-l pentru activități de securitate și utilizați generatoarele mai rapide pentru jocuri, simulări și date de testare.

Întrebări frecvente

Creați o instanță java.util.Random și apelați nextInt, nextLong, nextDouble, sau nextBoolean. Pentru o scurtă rezumat, utilizați Math.random care returnează o valoare double între 0.0 și 1.0. Ambele abordări sunt livrate cu biblioteca standard.

Apelați random.nextInt(max – min + 1) + min pentru numere întregi sau min + (max – min) * Math.random() pentru numere duble. Formulele scalează intervalul generatorului la fereastra țintă și se deplasează cu valoarea minimă.

Random este o clasă completă cu metode pentru multe tipuri primitive și acceptă însămânțarea. Math.random este un helper static care returnează o valoare double între 0.0 și 1.0. Intern, Math.random apelează o singură instanță partajată Random.

Da, dar apelurile concurente concurează pe aceeași valoare inițială internă, ceea ce încetinește codul puternic structurat pe fire de execuție. Folosește ThreadLocalRandom.current() din java.util.concurrent pentru a da fiecărui fir propriul generator și a elimina acea concurență.

Transmiteți o valoare long fixă ​​constructorului Random, de exemplu new Random(42), sau apelați setSeed(42). Generatorul va produce aceeași secvență la fiecare rulare, ceea ce este esențial pentru teste și simulări repetabile.

Folosiți SecureRandom ori de câte ori valoarea trebuie să reziste predicției, cum ar fi parolele, token-urile de sesiune, valorile salt, codurile de unică folosință și cheile criptografice. Aleator simplu este rapid, dar previzibil, deci nu este sigur pentru activitățile de securitate.

Framework-urile de învățare automată utilizează generatoare pseudo-aleatoare pentru a inițializa ponderile, a amesteca datele de antrenament și a diviza seturile de validare. Corectarea unei valori inițiale face ca experimentele să fie reproductibile, astfel încât echipele să poată compara rulările modelului și să depaneze rezultatele în mod fiabil.

Da. GitHub Copilot scheldează fragmentele Random, ThreadLocalRandom și SecureRandom, formulele de scalare a intervalului potrivite și JUnit teste. RevVizualizați fiecare sugestie pentru a confirma că clasa aleasă se potrivește cazului de utilizare, în special pentru codul sensibil din punct de vedere al securității.

Rezumați această postare cu: