Comment générer un nombre aléatoire dans Java

⚡ Résumé intelligent

nombres aléatoires dans Java proviennent de quatre options de bibliothèque standard apparentées : la classe Random, Math.random, ThreadLocalRandom et SecureRandom, chacune offrant un mélange différent de vitesse, de sécurité des threads et de robustesse cryptographique pour les applications réelles.

  • 🎲 Classe aléatoire : java.util.Random expose nextInt, nextLong, nextDouble, et nextBoolean pour les types primitifs courants.
  • 🧮 Math.random : Math.random renvoie un nombre décimal compris entre 0.0 inclus et 1.0 exclu en utilisant une instance Random partagée.
  • (I.e. Gammes personnalisées : Passez une limite à nextInt ou mettez à l'échelle Math.random pour générer des valeurs comprises entre un minimum et un maximum.
  • 🧵 Sécurité du fil : La fonction ThreadLocalRandom de java.util.concurrent attribue à chaque thread son propre générateur et surpasse un générateur Random partagé en cas de contention.
  • (I.e. Sécurité : SecureRandom dans java.security produit des valeurs cryptographiquement robustes pour les mots de passe, les jetons et les clés de session.
  • 🌱 Reproductibilité: Initialiser un nombre aléatoire avec une valeur longue fixe rend les tests et les simulations déterministes d'une exécution à l'autre.

Comment générer un nombre aléatoire dans Java

Les nombres aléatoires apparaissent partout dans Java, des données de tests unitaires et des jeux de dés aux jetons de session et aux paquets de cartes mélangés. Ce tutoriel explique comment générer des nombres aléatoires dans Java Utiliser toutes les options de la bibliothèque standard et choisir celle qui convient le mieux à la tâche.

Générer un nombre aléatoire dans Java

Le Java La bibliothèque standard propose quatre méthodes courantes pour générer un nombre aléatoire :

  • java.util.Random est la classe à usage général. Elle produit des valeurs booléennes, de type int, long, float et double grâce à des méthodes telles que : nextInt, nextLong et nextDouble.
  • Math.random est une fonction d'assistance statique qui renvoie un nombre décimal compris entre 0.0 (inclus) et 1.0 (exclu) en utilisant une variable partagée Random intérieurement.
  • ThreadLocalRandom in java.util.concurrent attribue à chaque thread son propre générateur, de sorte que plusieurs threads ne se disputent pas une même instance.
  • SecureRandom in java.security génère des nombres pseudo-aléatoires cryptographiquement robustes pour les mots de passe, les identifiants de session et les clés.

Les sections ci-dessous montrent comment générer dix nombres aléatoires avec chaque approche.

Exemple : générer un nombre aléatoire à l'aide de Java Classe aléatoire

Le premier exemple utilise java.util.Random produire dix entiers compris entre 0 et 99 inclus :

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

Sortie :

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

Une instance de Random est créé comme objGeneratorL’ nextInt(int bound) La méthode renvoie une valeur comprise entre 0 (inclus) et la limite fournie (exclue). nextInt(100) génère des valeurs de 0 à 99. Pour rendre la séquence reproductible, transmettez une graine au constructeur, par exemple : new Random(42); la même graine produit toujours la même séquence, ce qui est utile pour les tests et les simulations.

Exemple : Utiliser Java Math.aléatoire

Pour générer dix valeurs aléatoires comprises entre 0.0 et 1.0, appelez la fonction statique Math.random méthode à l'intérieur d'une boucleVoici la méthode la plus rapide pour obtenir un nombre décimal aléatoire sans créer d'objet générateur :

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

Sortie :

0.46518450373334297
0.14859851177803485
0.5628391820492477
0.6323378498048606
0.1740198445692248
0.9140544122258946
0.9167350036262347
0.49251219841030147
0.7426056725722353
0.2039418871298877

Sous la capuche, Math.random crée un seul statique Random lors de la première utilisation et des appels nextDouble Ce générateur unique partagé convient aux démonstrations, mais devient un goulot d'étranglement sous une charge multithread importante, problème que les sections suivantes abordent.

Générer un nombre aléatoire dans une plage personnalisée

Les programmes réels nécessitent généralement une valeur aléatoire comprise dans une plage spécifique, par exemple un entier entre 1 et 6 pour un lancer de dé ou un nombre décimal entre 10.0 et 20.0 pour une simulation. Deux modèles couvrent la quasi-totalité des cas.

Entier aléatoire compris entre min et max (inclus) :

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

Nombre décimal aléatoire compris entre min et max :

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

Les deux modèles fonctionnent en prenant une valeur de la plage native du générateur, en la mettant à l'échelle à la largeur de la plage cible et en la décalant vers le haut du minimum. Si vous êtes sur Java 8 ou version ultérieure, le même résultat est disponible via la version plus récente ints, longs et doubles méthodes de flux sur Random, Par exemple rnd.ints(10, 1, 7).forEach(System.out::println) pour dix lancers de dés.

ThreadLocalRandom pour le multithreading Code

Une seule personne partagée Random Il est sûr pour les threads, mais lent en cas de contention car chaque thread doit se synchroniser sur la même graine interne. ThreadLocalRandom, ajouté dans Java 7 et vivant à java.util.concurrent, attribue à chaque thread son propre générateur afin d'éviter tout conflit de verrouillage.

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

Utilisez le ThreadLocalRandom.current() à l'intérieur des threads de travail, des flux parallèles et de toute tâche concurrente. Notez que setSeed jette UnsupportedOperationExceptionL'amorçage pour la reproductibilité n'est donc pas pris en charge ; si vous avez besoin d'une valeur d'amorçage fixe, utilisez la valeur par défaut. Random.

SecureRandom pour la génération aléatoire sensible à la sécurité Numbers

Les instances de Random et ThreadLocalRandom ne sont pas cryptographiquement sûrs. À partir de quelques exemples de sortie, un attaquant peut reconstituer l'état interne et prédire les valeurs futures. Pour les mots de passe, les jetons de session, les valeurs de sel et les clés cryptographiques, utilisez java.security.SecureRandom Au lieu de cela, il puise des données initiales dans le pool d'entropie du système d'exploitation et produit des valeurs imprévisibles.

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 est plus lent que Random Il utilise des algorithmes plus robustes et des données initiales plus riches. Réservez-le aux tâches de sécurité et privilégiez les générateurs plus rapides pour les jeux, les simulations et les données de test.

FAQ

Créez une instance de java.util.Random et appelez nextInt, nextLong, nextDouble`nextBoolean` ou `Math.random`. Pour une solution rapide en une seule ligne, utilisez `Math.random` qui renvoie un nombre décimal entre 0.0 et 1.0. Ces deux méthodes sont disponibles dans la bibliothèque standard.

Appelez `random.nextInt(max – min + 1) + min` pour les entiers, ou `min + (max – min) * Math.random()` pour les nombres à virgule flottante. Les formules adaptent la plage du générateur à votre fenêtre cible et effectuent un décalage de la valeur minimale.

La classe Random est une classe complète dotée de méthodes pour de nombreux types primitifs et prend en charge l'initialisation. La méthode Math.random est une fonction statique utilitaire qui renvoie un nombre décimal compris entre 0.0 et 1.0. En interne, Math.random appelle une instance unique et partagée de Random.

Oui, mais les appels simultanés se disputent la même graine interne, ce qui ralentit le code multithreadé. Utilisez `ThreadLocalRandom.current()` de `java.util.concurrent` pour attribuer à chaque thread son propre générateur et ainsi éviter cette contention.

Passez un entier long fixe au constructeur Random, par exemple new Random(42), ou appelez setSeed(42). Le générateur produira la même séquence à chaque exécution, ce qui est essentiel pour des tests et des simulations reproductibles.

Utilisez SecureRandom lorsque la valeur doit être imprévisible, comme pour les mots de passe, les jetons de session, les valeurs de sel, les codes à usage unique et les clés cryptographiques. Plain Random est rapide mais prévisible, et donc non sécurisé pour les applications de sécurité.

Les frameworks d'apprentissage automatique utilisent des générateurs pseudo-aléatoires pour initialiser les poids, mélanger les données d'entraînement et diviser les ensembles de validation. Fixer la valeur initiale permet de reproduire les expériences, ce qui facilite la comparaison des exécutions de modèles et le débogage fiable des résultats.

Oui. GitHub Copilot génère des extraits de code Random, ThreadLocalRandom et SecureRandom, en faisant correspondre les formules de mise à l'échelle des plages, et JUnit Des tests. RevExaminez chaque suggestion pour confirmer que la classe choisie correspond au cas d'utilisation, en particulier pour le code sensible en matière de sécurité.

Résumez cet article avec :