Come generare un numero casuale in Java

โšก Riepilogo intelligente

Numeri casuali in Java derivano da quattro opzioni correlate della libreria standard: la classe Random, Math.random, ThreadLocalRandom e SecureRandom, ognuna delle quali offre una diversa combinazione di velocitร , sicurezza dei thread e robustezza crittografica per applicazioni reali.

  • ๐ŸŽฒ Classe casuale: java.util.Random espone nextInt, nextLong, nextDoublee nextBoolean per i tipi primitivi comuni.
  • ๐Ÿงฎ Matematica casuale: Math.random restituisce un valore double compreso tra 0.0 (incluso) e 1.0 (escluso) utilizzando un'istanza Random condivisa.
  • ๐ŸŽฏ Intervalli personalizzati: Passa un limite a nextInt o scala Math.random per generare valori compresi tra un minimo e un massimo qualsiasi.
  • ๐Ÿงต Sicurezza delle filettature: ThreadLocalRandom in java.util.concurrent assegna a ciascun thread un generatore di numeri casuali dedicato e offre prestazioni superiori rispetto a un generatore di numeri casuali condiviso in condizioni di contesa.
  • ๐Ÿ” Sicurezza: SecureRandom in java.security produce valori crittograficamente sicuri per password, token e chiavi di sessione.
  • ๐ŸŒฑ Riproducibilitร : L'inserimento di un valore di inizializzazione fisso in un generatore di numeri casuali rende i test e le simulazioni deterministici tra le diverse esecuzioni.

Come generare un numero casuale in Java

I numeri casuali appaiono ovunque in Java, dai dati dei test unitari e dai giochi di lancio dei dadi ai token di sessione e ai mazzi mescolati. Questo tutorial spiega come generare numeri casuali in Java Utilizzo di tutte le opzioni della libreria standard e come scegliere quella piรน adatta allo scopo.

Generare un numero casuale in Java

Migliori Java La libreria standard offre quattro metodi comuni per generare un numero casuale:

  • java.util.Random รจ la classe generica. Produce valori booleani, int, long, float e double tramite metodi come nextInt, nextLonge nextDouble.
  • Math.random รจ un helper statico che restituisce un double compreso tra 0.0 (incluso) e 1.0 (escluso) utilizzando un condiviso Random internamente.
  • ThreadLocalRandom in java.util.concurrent assegna a ciascun thread il proprio generatore, in modo che piรน thread non entrino in competizione per una singola istanza.
  • SecureRandom in java.security Genera numeri pseudo-casuali crittograficamente sicuri per password, identificativi di sessione e chiavi.

Le sezioni seguenti mostrano come generare dieci numeri casuali con ciascun metodo.

Esempio: Generare un numero casuale utilizzando Java Classe casuale

Il primo esempio utilizza java.util.Random produrre dieci numeri interi compresi tra 0 e 99 inclusi:

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

Produzione:

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'istanza di Random viene creato come objGenerator. nextInt(int bound) il metodo restituisce un valore compreso tra 0 (incluso) e il limite fornito (escluso), quindi nextInt(100) produce valori da 0 a 99. Per rendere la sequenza riproducibile, passa un seme al costruttore, ad esempio new Random(42); lo stesso seme produce sempre la stessa sequenza, il che รจ utile nei test e nelle simulazioni.

Esempio: utilizzo Java Matematica casuale

Per generare dieci valori casuali nell'intervallo da 0.0 a 1.0, chiama la funzione statica Math.random metodo all'interno di un loopQuesto รจ il modo piรน veloce per ottenere un numero decimale casuale senza creare un oggetto generatore:

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

Produzione:

0.46518450373334297
0.14859851177803485
0.5628391820492477
0.6323378498048606
0.1740198445692248
0.9140544122258946
0.9167350036262347
0.49251219841030147
0.7426056725722353
0.2039418871298877

Sotto il cappuccio, Math.random crea un singolo statico Random al primo utilizzo e alle chiamate nextDouble su di esso. Quel singolo generatore condiviso va bene per le demo, ma diventa un collo di bottiglia sotto un carico multithread pesante, che verrร  affrontato nelle sezioni successive.

Genera un numero casuale in un intervallo personalizzato

I programmi reali in genere necessitano di un valore casuale all'interno di un intervallo specifico, come un numero intero tra 1 e 6 per il lancio di un dado o un numero decimale tra 10.0 e 20.0 per una simulazione. Due modelli coprono quasi tutti i casi.

Numero intero casuale compreso tra min e max (inclusi):

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

Numero decimale casuale compreso tra min e max:

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

Entrambi i modelli funzionano prendendo un valore dall'intervallo nativo del generatore, scalandolo alla larghezza dell'intervallo di destinazione e spostandolo verso l'alto del minimo. Se ti trovi su Java 8 o versioni successive, lo stesso risultato รจ disponibile tramite le versioni piรน recenti ints, longse doubles metodi di streaming su Randomdi strumenti adatti, questi rnd.ints(10, 1, 7).forEach(System.out::println) per dieci lanci di dadi.

ThreadLocalRandom per Multithreaded Code

Un unico condiviso Random รˆ thread-safe ma lento in condizioni di contesa perchรฉ ogni thread deve sincronizzarsi con lo stesso seed interno. ThreadLocalRandom, aggiunto in Java 7 e vivendo in java.util.concurrent, assegna a ciascun thread il proprio generatore in modo che non vi sia contesa di blocco.

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

Usa il ThreadLocalRandom.current() all'interno dei thread di lavoro, dei flussi paralleli e di qualsiasi attivitร  concorrente. Si noti che setSeed getta UnsupportedOperationException, quindi il seeding per la riproducibilitร  non รจ supportato; se hai bisogno di un seed fisso, attieniti al semplice Random.

SecureRandom per la generazione casuale sensibile alla sicurezza Numbers

Le istanze di Random and ThreadLocalRandom non sono crittograficamente sicuri. Dati alcuni campioni di output, un attaccante puรฒ ricostruire lo stato interno e prevedere i valori futuri. Per password, token di sessione, valori salt e chiavi crittografiche, utilizzare java.security.SecureRandom Al contrario, attinge materiale di partenza dal pool di entropia del sistema operativo e produce valori che resistono a qualsiasi previsione.

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 รจ piรน lento di Random perchรฉ utilizza algoritmi piรน potenti e materiale di partenza piรน ricco. Riservatelo ai lavori di sicurezza e utilizzate i generatori piรน veloci per giochi, simulazioni e dati di test.

DOMANDE FREQUENTI

Crea un'istanza di java.util.Random e chiama nextInt, nextLong, nextDoubleoppure nextBoolean. Per una soluzione rapida in una sola riga, usa Math.random che restituisce un valore double compreso tra 0.0 e 1.0. Entrambi gli approcci sono inclusi nella libreria standard.

Per i numeri interi, chiama random.nextInt(max โ€“ min + 1) + min, oppure min + (max โ€“ min) * Math.random() per i numeri decimali. Le formule scalano l'intervallo del generatore alla finestra di destinazione e lo spostano del valore minimo.

Random รจ una classe completa con metodi per molti tipi primitivi e supporta l'inizializzazione. Math.random รจ una funzione di supporto statica che restituisce un valore double compreso tra 0.0 e 1.0. Internamente, Math.random richiama una singola istanza condivisa di Random.

Sรฌ, ma le chiamate concorrenti si contendono lo stesso seed interno, il che rallenta il codice che fa un uso intensivo dei thread. Utilizza ThreadLocalRandom.current() da java.util.concurrent per assegnare a ciascun thread il proprio generatore ed eliminare tale contesa.

Passa un valore long fisso al costruttore di Random, ad esempio new Random(42), oppure chiama setSeed(42). Il generatore produrrร  la stessa sequenza a ogni esecuzione, il che รจ essenziale per test e simulazioni ripetibili.

Utilizza SecureRandom ogni volta che il valore deve essere immune alla previsione, come nel caso di password, token di sessione, valori salt, codici monouso e chiavi crittografiche. Plain Random รจ veloce ma prevedibile, quindi non รจ sicuro per applicazioni di sicurezza.

I framework di machine learning utilizzano generatori pseudo-casuali per inizializzare i pesi, mescolare i dati di addestramento e suddividere i set di validazione. Fissare un seed rende gli esperimenti riproducibili, consentendo ai team di confrontare le esecuzioni dei modelli ed eseguire il debug dei risultati in modo affidabile.

Sรฌ. GitHub Copilot genera frammenti Random, ThreadLocalRandom e SecureRandom, abbinando formule di ridimensionamento dell'intervallo e JUnit test. RevEsaminate attentamente ogni suggerimento per verificare che la classe scelta sia adatta al caso d'uso, soprattutto per il codice sensibile alla sicurezza.

Riassumi questo post con: