Comment générer des entiers aléatoires dans une plage spécifique en Java?

3508

Comment générer une intvaleur aléatoire dans une plage spécifique?

J'ai essayé ce qui suit, mais ceux-ci ne fonctionnent pas:

Tentative 1:

randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.

Tentative 2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.
user42155
la source
Lorsque vous avez besoin de nombreux nombres aléatoires, je ne recommande pas la classe Random dans l'API. Il a juste une période trop courte. Essayez plutôt le twister Mersenne . Il existe une implémentation Java .
raupach
1
Avant de publier une nouvelle réponse, considérez qu'il existe déjà plus de 65 réponses à cette question. Veuillez vous assurer que votre réponse fournit des informations qui ne figurent pas parmi les réponses existantes.
janniks

Réponses:

3804

Dans Java 1.7 ou version ultérieure , la manière standard de procéder est la suivante:

import java.util.concurrent.ThreadLocalRandom;

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);

Voir le JavaDoc correspondant . Cette approche présente l'avantage de ne pas avoir à initialiser explicitement une instance java.util.Random , qui peut être une source de confusion et d'erreur si elle est utilisée de manière inappropriée.

Cependant, à l'inverse, il n'y a aucun moyen de définir explicitement la graine, il peut donc être difficile de reproduire les résultats dans des situations où cela est utile, comme tester ou enregistrer des états de jeu ou similaires. Dans ces situations, la technique pré-Java 1.7 illustrée ci-dessous peut être utilisée.

Avant Java 1.7 , la manière standard de procéder est la suivante:

import java.util.Random;

/**
 * Returns a pseudo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * <code>Integer.MAX_VALUE - 1</code>.
 *
 * @param min Minimum value
 * @param max Maximum value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public static int randInt(int min, int max) {

    // NOTE: This will (intentionally) not run as written so that folks
    // copy-pasting have to think about how to initialize their
    // Random instance.  Initialization of the Random instance is outside
    // the main scope of the question, but some decent options are to have
    // a field that is initialized once and then re-used as needed or to
    // use ThreadLocalRandom (if using at least Java 1.7).
    // 
    // In particular, do NOT do 'Random rand = new Random()' here or you
    // will get not very good / not very random results.
    Random rand;

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

Voir le JavaDoc correspondant . En pratique, la classe java.util.Random est souvent préférable à java.lang.Math.random () .

En particulier, il n'est pas nécessaire de réinventer la roue de génération d'entiers aléatoires lorsqu'il existe une API simple dans la bibliothèque standard pour accomplir la tâche.

Greg Case
la source
43
Pour les appels où la maxvaleur est, Integer.MAX_VALUEil est possible de déborder, résultant en un java.lang.IllegalArgumentException. Vous pouvez essayer avec: randInt(0, Integer.MAX_VALUE). De plus, si nextInt((max-min) + 1)renvoie la valeur la plus élevée (assez rare, je suppose) ne débordera-t-elle pas à nouveau (en supposant que min et max soient des valeurs suffisamment élevées)? Comment faire face à ce genre de situations?
Daniel
3
@MoisheLipsker Il faut que nextLong ne prenne pas de limite en tant que nextInteger
mmm
13
@leventov a ThreadLocalRandomété ajouté à Java 2 ans et demi après la première question posée. J'ai toujours été fermement convaincu que la gestion de l'instance aléatoire est hors de portée de la question.
Greg Case
6
Dans Android Random rand = new Random ();
Webserveis
5
@Webserveis Ceci est traité dans les commentaires de l'exemple. Version courte - vous ne devriez pas = nouveau Random () pour chaque appel à la fonction, ou vos résultats ne seront pas suffisamment aléatoires pour de nombreux cas.
Greg Case
1422

Notez que cette approche est plus biaisée et moins efficace qu'une nextIntapproche, https://stackoverflow.com/a/738651/360211

Un modèle standard pour y parvenir est:

Min + (int)(Math.random() * ((Max - Min) + 1))

La fonction de bibliothèque Java Math Math.random () génère une valeur double dans la plage [0,1). Notez que cette plage n'inclut pas le 1.

Pour obtenir d'abord une plage de valeurs spécifique, vous devez multiplier par l'ampleur de la plage de valeurs que vous souhaitez couvrir.

Math.random() * ( Max - Min )

Cela renvoie une valeur dans la plage [0,Max-Min), où «Max-Min» n'est pas inclus.

Par exemple, si vous le souhaitez [5,10), vous devez couvrir cinq valeurs entières pour utiliser

Math.random() * 5

Cela retournerait une valeur dans la plage [0,5), où 5 n'est pas inclus.

Vous devez maintenant déplacer cette plage jusqu'à la plage que vous ciblez. Pour ce faire, ajoutez la valeur Min.

Min + (Math.random() * (Max - Min))

Vous obtiendrez maintenant une valeur dans la plage [Min,Max). Suivant notre exemple, cela signifie [5,10):

5 + (Math.random() * (10 - 5))

Mais cela n'inclut toujours pas Maxet vous obtenez une valeur double. Pour obtenir la Maxvaleur incluse, vous devez ajouter 1 à votre paramètre de plage (Max - Min), puis tronquer la partie décimale en effectuant un transtypage en entier. Cela se fait via:

Min + (int)(Math.random() * ((Max - Min) + 1))

Et voila. Une valeur entière aléatoire dans la plage [Min,Max], ou selon l'exemple [5,10]:

5 + (int)(Math.random() * ((10 - 5) + 1))
TJ_Fischer
la source
82
La documentation de Sun dit explicitement que vous devriez mieux utiliser Random () si vous avez besoin d'un int au lieu de Math.random () qui produit un double.
Lilian A. Moraru
6
Ceci est en fait biaisé par rapport aux méthodes nextInt stackoverflow.com/a/738651/360211
weston
4
Dans ce cas, "biaisé" signifie qu'après 2 ^ 53 exécutions, certains numéros auront eu une occurrence supplémentaire, en moyenne.
Céphalopode
378

Utilisation:

Random ran = new Random();
int x = ran.nextInt(6) + 5;

L'entier xest maintenant le nombre aléatoire dont le résultat est possible 5-10.

Martijn Pieters
la source
159

Utilisation:

minimum + rn.nextInt(maxValue - minvalue + 1)
krosenvold
la source
137

Avec ils ont introduit la méthode ints(int randomNumberOrigin, int randomNumberBound)dans la Randomclasse.

Par exemple, si vous souhaitez générer cinq entiers aléatoires (ou un seul) dans la plage [0, 10], faites simplement:

Random r = new Random();
int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray();
int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt();

Le premier paramètre indique juste la taille du IntStreamgénéré (qui est la méthode surchargée de celle qui produit un nombre illimité IntStream).

Si vous devez effectuer plusieurs appels distincts, vous pouvez créer un itérateur primitif infini à partir du flux:

public final class IntRandomNumberGenerator {

    private PrimitiveIterator.OfInt randomIterator;

    /**
     * Initialize a new random number generator that generates
     * random numbers in the range [min, max]
     * @param min - the min value (inclusive)
     * @param max - the max value (inclusive)
     */
    public IntRandomNumberGenerator(int min, int max) {
        randomIterator = new Random().ints(min, max + 1).iterator();
    }

    /**
     * Returns a random number in the range (min, max)
     * @return a random number in the range (min, max)
     */
    public int nextInt() {
        return randomIterator.nextInt();
    }
}

Vous pouvez également le faire pour doubleet des longvaleurs. J'espère que ça aide! :)

Alexis C.
la source
1
Je suggère que vous instanciez randomIterator une seule fois. Voir le commentaire de Greg Case sur sa propre réponse.
Naxos84
si vous le pouvez, pouvez-vous expliquer quelle est la signification du streamSize- premier paramètre de cette méthode donné streamSize !=0. Quelle est la différence si streamSize1/2 / n est donné?
Erfan Ahmed
104

Vous pouvez modifier votre deuxième exemple de code pour:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;
Bill le lézard
la source
100

Une petite modification de votre première solution suffirait.

Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);

Voir plus ici pour la mise en œuvre de Random

hexabunny
la source
Pour minimum <= valeur <maximum, j'ai fait la même chose avec Math: randomNum = minimum + (int) (Math.random () * (maximum-minimum)); mais le casting n'est pas vraiment sympa à voir;)
AxelH
Réponse en double d'au moins 7 ans en retard.
Maarten Bodewes
70

ThreadLocalRandoméquivalent de classe java.util.Randompour un environnement multithread. La génération d'un nombre aléatoire est effectuée localement dans chacun des threads. Nous avons donc une meilleure performance en réduisant les conflits.

int rand = ThreadLocalRandom.current().nextInt(x,y);

x, y- intervalles par exemple (1,10)

andrew
la source
66

La Math.Randomclasse en Java est basée sur 0. Donc, si vous écrivez quelque chose comme ça:

Random rand = new Random();
int x = rand.nextInt(10);

xsera entre 0-9inclus.

Donc, étant donné le tableau d' 25éléments suivant, le code pour générer un nombre aléatoire entre 0(la base du tableau) et array.lengthserait:

String[] i = new String[25];
Random rand = new Random();
int index = 0;

index = rand.nextInt( i.length );

Puisque i.lengthreviendra 25, le nextInt( i.length )renverra un nombre entre la plage de 0-24. L'autre option va avec Math.Randomqui fonctionne de la même manière.

index = (int) Math.floor(Math.random() * i.length);

Pour une meilleure compréhension, consultez le post du forum Intervalles aléatoires (archive.org) .

Matt R
la source
+1 pour le lien de capture d'écran de l'archive wayBackMachine et votre réponse est toujours une référence utile pour obtenir des nombres "aléatoires" avec / dans une plage.
Tapper7
Cela me déconcerte pourquoi vous instanciez l'index à 0.
AjahnCharles
@CodeConfident La indexvariable n'affectera pas le résultat du nombre aléatoire. Vous pouvez choisir de l'initialiser comme vous le souhaitez sans avoir à vous soucier de changer le résultat. J'espère que cela t'aides.
Matt R
Exactement ... c'est complètement inutilisé. Je l'initialiserais directement au rand:int index = rand.nextInt(i.Length);
AjahnCharles
Ou pas du tout. int index; \n index = rand...si l'on aime les déclarations et les affectations sur des lignes différentes. Certaines normes de codage sont plus strictes (et sans but apparent) que d'autres.
Mark Storer
49

Pardonnez-moi d'être fastidieux, mais la solution suggérée par la majorité, c'est-à-dire min + rng.nextInt(max - min + 1)), semble périlleuse du fait que:

  • rng.nextInt(n)ne peut pas atteindre Integer.MAX_VALUE.
  • (max - min)peut provoquer un débordement lorsqu'il minest négatif.

Une solution infaillible retournerait des résultats corrects pour tout min <= maxdans [ Integer.MIN_VALUE, Integer.MAX_VALUE]. Considérez l'implémentation naïve suivante:

int nextIntInRange(int min, int max, Random rng) {
   if (min > max) {
      throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "].");
   }
   int diff = max - min;
   if (diff >= 0 && diff != Integer.MAX_VALUE) {
      return (min + rng.nextInt(diff + 1));
   }
   int i;
   do {
      i = rng.nextInt();
   } while (i < min || i > max);
   return i;
}

Bien qu'inefficace, notez que la probabilité de succès dans la whileboucle sera toujours de 50% ou plus.

Joel Sjöstrand
la source
Pourquoi ne pas lever une exception IllegalArgumentException lorsque la différence = Integer.MAX_VALUE? Ensuite, vous n'avez pas besoin de la boucle while.
MP Korstanje
3
@mpkorstanje Cette implémentation est conçue pour fonctionner avec toutes les valeurs de min <= max, même lorsque leur différence est égale ou même supérieure à MAX_VALUE. L'exécution d'une boucle jusqu'à la réussite est un modèle courant dans ce cas, pour garantir une distribution uniforme (si la source sous-jacente de l'aléatoire est uniforme). Random.nextInt (int) le fait en interne lorsque l'argument n'est pas une puissance de 2.
Christian Semrau
44

Cela peut être fait en faisant simplement la déclaration:

Randomizer.generate(0,10); //min of zero, max of ten

Voici son code source

Randomizer.java

public class Randomizer {
    public static int generate(int min,int max) {
        return min + (int)(Math.random() * ((max - min) + 1));
    }
}

C'est juste propre et simple.

Abel Callejo
la source
5
Cela aurait pu être une modification de l'autre exemple, maintenant ce n'est qu'une copie flagrante de la réputation. Souligner que la "réponse avec le plus de votes" n'est pas non plus très directe, elle peut changer.
Maarten Bodewes
1
C'est vrai @MaartenBodewes. Lorsque j'ai écrit cette réponse, la réponse avec le plus de votes ci-dessus était toujours écrite comme une solution de type algorithme. Maintenant, la solution ci-dessus a beaucoup changé et maintenant cette réponse ressemblait à une copie-chat.
Abel Callejo
Je ne comprends vraiment pas pourquoi de tels bits de code fondamentaux ne font pas partie des bibliothèques standard Java. Pourquoi dois-je implémenter cela?
Leevi L
31

Prenons un exemple.

Supposons que je souhaite générer un nombre compris entre 5 et 10 :

int max = 10;
int min = 5;
int diff = max - min;
Random rn = new Random();
int i = rn.nextInt(diff + 1);
i += min;
System.out.print("The Random Number is " + i);

Comprenons cela ...

Initialisez max avec la valeur la plus élevée et min avec la valeur la plus basse.

Maintenant, nous devons déterminer combien de valeurs possibles peuvent être obtenues. Pour cet exemple, ce serait:

5, 6, 7, 8, 9, 10

Donc, le décompte serait max - min + 1.

soit 10 - 5 + 1 = 6

Le nombre aléatoire générera un nombre compris entre 0 et 5 .

soit 0, 1, 2, 3, 4, 5

L'ajout de la valeur min au nombre aléatoire produirait:

5, 6, 7, 8, 9, 10

On obtient donc la plage souhaitée.

Sunil Chawla
la source
29
 rand.nextInt((max+1) - min) + min;
Michael Myers
la source
26

Générez un nombre aléatoire pour la différence de min et max en utilisant la méthode nextint (n) , puis ajoutez un nombre min au résultat:

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
gifpif
la source
26

J'utilise ceci:

 /**
   * @param min - The minimum.
   * @param max - The maximum.
   * @return A random double between these numbers (inclusive the minimum and maximum).
   */
 public static double getRandom(double min, double max) {
   return (Math.random() * (max + 1 - min)) + min;
 }

Vous pouvez le convertir en entier si vous le souhaitez.

Simon
la source
Cette fonction produit encore et encore le même nombre. Dans mon cas, c'était: 2147483647
sokras
Echec: vous avez une fonction qui nécessite un double puis effectuez + 1? Cela va certainement à l'encontre du principe de la moindre surprise. Que se passe-t-il si vous utilisez min = 0,1 et max = 0,2?
Maarten Bodewes
@sokras la méthode appelle new Random(vérifiez JavaDoc): "Crée un nouveau générateur de nombres aléatoires. Ce constructeur définit la graine du générateur de nombres aléatoires à une valeur très probablement distincte de toute autre invocation de ce constructeur." Très probablement pourrait simplement impliquer d'utiliser l'heure actuelle comme graine. Si ce temps utilise des millisecondes, les ordinateurs actuels sont suffisamment rapides pour générer le même nombre. Mais outre que 2147483647 est Integer.MAX_VALUE; la sortie dépend évidemment de l'entrée que vous n'avez pas spécifiée.
Maarten Bodewes
Enfin trouvé celui qui fonctionne réellement
Jency
23

Depuis Java 7, vous ne devriez plus utiliser Random. Pour la plupart des utilisations, le générateur de nombres aléatoires de choix est maintenant ThreadLocalRandom.

Pour les pools de jointures de fourches et les flux parallèles, utilisez SplittableRandom.

Joshua Bloch. Java efficace. Troisième édition.

À partir de Java 8

Pour les pools de jointures de fourches et les flux parallèles, l'utilisation SplittableRandomqui est généralement plus rapide, a une meilleure indépendance statistique et des propriétés d'uniformité par rapport à Random.

Pour générer un aléatoire intdans la plage[0, 1_000]:

int n = new SplittableRandom().nextInt(0, 1_001);

Pour générer un int[100]tableau aléatoire de valeurs dans la plage[0, 1_000]:

int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray();

Pour renvoyer un flux de valeurs aléatoires:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
Oleksandr Pyrohov
la source
Y a-t-il une raison pour laquelle l'exemple inclut un .parallel()? Il me semble que générer 100 nombres aléatoires serait trop trivial pour justifier le parallélisme.
Johnbot
@Johnbot Merci pour le commentaire, vous avez raison. Mais, la raison principale était de montrer une API (bien sûr, le chemin intelligent est de mesurer les performances avant d'utiliser le paralleltraitement). Soit dit en passant, pour un tableau d' 1_000_000éléments, la parallelversion était 2 fois plus rapide sur ma machine par rapport au séquentiel.
Oleksandr Pyrohov
21

Utilisez simplement la classe Random :

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
Prof Mo
la source
8
Je ne vois rien de nouveau ici qui n'avait pas été publié dans d'innombrables articles précédents.
Maarten Bodewes
20

Ces méthodes peuvent être pratiques à utiliser:

Cette méthode renverra un nombre aléatoire entre la valeur min et max fournie:

public static int getRandomNumberBetween(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt(max - min) + min;
    if (randomNumber == min) {
        // Since the random number is between the min and max values, simply add 1
        return min + 1;
    } else {
        return randomNumber;
    }
}

et cette méthode renverra un nombre aléatoire à partir des valeurs min et max fournies (donc le nombre généré pourrait également être le nombre min ou max):

public static int getRandomNumberFrom(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt((max + 1) - min) + min;

    return randomNumber;
}
Luke Taylor
la source
// Since the random number is between the min and max values, simply add 1. Pourquoi? Ne compte pas min? Habituellement, la plage est [min, max) où min est inclus et max est exclu. Mauvaise réponse, rejetée.
Maarten Bodewes
@MaartenBodewes +1 est ajouté car getRandomNumberBetween génère un nombre aléatoire à l'exclusion des points de terminaison fournis.
Luke Taylor
1
Le nombre min + 1sera deux fois plus probable que l'autre résultat getRandomNumberBetween!
Lii
19

En cas de lancer un dé, ce serait un nombre aléatoire compris entre 1 et 6 (pas entre 0 et 6), donc:

face = 1 + randomNumbers.nextInt(6);
sam
la source
19
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();

Ou jetez un œil à RandomUtils d' Apache Commons .

user2427
la source
C'est utile, mais méfiez-vous d'un petit défaut: les signatures de méthode sont comme: nextDouble (double startInclusive, double endInclusive), mais si vous regardez à l'intérieur des méthodes, endInclusive devrait en fait être endExclusive.
zakmck
Double.valueOf(Math.random()*(maximum-minimun)).intValue()est une façon assez obscure (et inefficace) de dire (int)(Math.random()*(maximum-minimun))
Holger
Discordance d'orthographe pour le retour minimum minimum + Double.valueOf (Math.random () * (maximum - minimum)). IntValue ();
Hrishikesh Mishra
18

Voici une classe utile pour générer au hasard intsdans une plage avec n'importe quelle combinaison de limites inclusives / exclusives:

import java.util.Random;

public class RandomRange extends Random {
    public int nextIncInc(int min, int max) {
        return nextInt(max - min + 1) + min;
    }

    public int nextExcInc(int min, int max) {
        return nextInt(max - min) + 1 + min;
    }

    public int nextExcExc(int min, int max) {
        return nextInt(max - min - 1) + 1 + min;
    }

    public int nextIncExc(int min, int max) {
        return nextInt(max - min) + min;
    }
}
Garrett Hall
la source
18

Pour générer un nombre aléatoire "entre deux nombres", utilisez le code suivant:

Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;

Cela vous donne un nombre aléatoire compris entre 1 (inclus) et 11 (exclusif), donc initialisez la valeur upperBound en ajoutant 1. Par exemple, si vous voulez générer un nombre aléatoire entre 1 et 10, initialisez le nombre upperBound avec 11 au lieu de dix.

Lawakush Kurmi
la source
18

Vous pouvez y parvenir de manière concise en Java 8:

Random random = new Random();

int max = 10;
int min = 5;
int totalNumber = 10;

IntStream stream = random.ints(totalNumber, min, max);
stream.forEach(System.out::println);
Mulalo Madida
la source
17
public static Random RANDOM = new Random(System.nanoTime());

public static final float random(final float pMin, final float pMax) {
    return pMin + RANDOM.nextFloat() * (pMax - pMin);
}
AZ_
la source
16

Une autre option utilise simplement Apache Commons :

import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;

public void method() {
    RandomData randomData = new RandomDataImpl();
    int number = randomData.nextInt(5, 10);
    // ...
 }
gerardw
la source
16

J'ai trouvé cet exemple Générer des nombres aléatoires :


Cet exemple génère des entiers aléatoires dans une plage spécifique.

import java.util.Random;

/** Generate random integers in a certain range. */
public final class RandomRange {

  public static final void main(String... aArgs){
    log("Generating random integers in the range 1..10.");

    int START = 1;
    int END = 10;
    Random random = new Random();
    for (int idx = 1; idx <= 10; ++idx){
      showRandomInteger(START, END, random);
    }

    log("Done.");
  }

  private static void showRandomInteger(int aStart, int aEnd, Random aRandom){
    if ( aStart > aEnd ) {
      throw new IllegalArgumentException("Start cannot exceed End.");
    }
    //get the range, casting to long to avoid overflow problems
    long range = (long)aEnd - (long)aStart + 1;
    // compute a fraction of the range, 0 <= frac < range
    long fraction = (long)(range * aRandom.nextDouble());
    int randomNumber =  (int)(fraction + aStart);    
    log("Generated : " + randomNumber);
  }

  private static void log(String aMessage){
    System.out.println(aMessage);
  }
} 

Un exemple d'exécution de cette classe:

Generating random integers in the range 1..10.
Generated : 9
Generated : 3
Generated : 3
Generated : 9
Generated : 4
Generated : 1
Generated : 3
Generated : 9
Generated : 10
Generated : 10
Done.
Hospes
la source
14

Il vaut mieux utiliser SecureRandom plutôt que simplement Random.

public static int generateRandomInteger(int min, int max) {
    SecureRandom rand = new SecureRandom();
    rand.setSeed(new Date().getTime());
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}
grep
la source
1
Ce n'est pas si bon, car s'il est exécuté dans la même mili seconde alors vous obtiendrez le même nombre, vous devez mettre l'initialisation rand et le setSeet en dehors de la méthode.
maraca du
Vous avez besoin de semences, oui, mais en utilisant SecureRandom.
grep
Je suis désolé, mais celui qui a rejeté la demande de changement n'a aucune idée de la programmation Java.C'est une bonne suggestion, mais comme c'est faux, car s'il est exécuté dans la même mili seconde, il donnera le même numéro, pas au hasard.
maraca
La bonne solution n'est nulle part trouvée, peu de gens connaissent les blocs d'initialisation statiques ... c'est ce que vous devez utiliser pour définir la valeur de départ: 1: private static int SecureRandom rand = new SecureRandom();2: static {3: rand.setSeed(...);4:}
maraca
5
Il n'est absolument pas nécessaire de semer SecureRandom, il sera semé par le système. L'appel direct setSeedest très dangereux, il peut remplacer la graine (vraiment aléatoire) par la date. Et cela n'aboutira certainement pas à un SecureRandom, car tout le monde peut deviner le temps et essayer de semer sa propre SecureRandominstance avec ces informations.
Maarten Bodewes
13

Voici un exemple simple qui montre comment générer un nombre aléatoire à partir d'une [min, max]plage fermée , tout enmin <= max is true

Vous pouvez le réutiliser comme champ dans la classe de trous, en ayant également toutes les Random.classméthodes au même endroit

Exemple de résultats:

RandomUtils random = new RandomUtils();
random.nextInt(0, 0); // returns 0
random.nextInt(10, 10); // returns 10
random.nextInt(-10, 10); // returns numbers from -10 to 10 (-10, -9....9, 10)
random.nextInt(10, -10); // throws assert

Sources:

import junit.framework.Assert;
import java.util.Random;

public class RandomUtils extends Random {

    /**
     * @param min generated value. Can't be > then max
     * @param max generated value
     * @return values in closed range [min, max].
     */
    public int nextInt(int min, int max) {
        Assert.assertFalse("min can't be > then max; values:[" + min + ", " + max + "]", min > max);
        if (min == max) {
            return max;
        }

        return nextInt(max - min + 1) + min;
    }
}
Yakiv Mospan
la source
13
rand.nextInt((max+1) - min) + min;

Cela fonctionne bien.

ganesh
la source