Comment générer une int
valeur 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`.
Réponses:
Dans Java 1.7 ou version ultérieure , la manière standard de procéder est la suivante:
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:
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.
la source
max
valeur est,Integer.MAX_VALUE
il est possible de déborder, résultant en unjava.lang.IllegalArgumentException
. Vous pouvez essayer avec:randInt(0, Integer.MAX_VALUE)
. De plus, sinextInt((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?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.Notez que cette approche est plus biaisée et moins efficace qu'une
nextInt
approche, https://stackoverflow.com/a/738651/360211Un modèle standard pour y parvenir est:
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.
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 utiliserCela 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.
Vous obtiendrez maintenant une valeur dans la plage
[Min,Max)
. Suivant notre exemple, cela signifie[5,10)
:Mais cela n'inclut toujours pas
Max
et vous obtenez une valeur double. Pour obtenir laMax
valeur 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:Et voila. Une valeur entière aléatoire dans la plage
[Min,Max]
, ou selon l'exemple[5,10]
:la source
Utilisation:
L'entier
x
est maintenant le nombre aléatoire dont le résultat est possible5-10
.la source
Utilisation:
la source
Avec java-8ils ont introduit la méthode
ints(int randomNumberOrigin, int randomNumberBound)
dans laRandom
classe.Par exemple, si vous souhaitez générer cinq entiers aléatoires (ou un seul) dans la plage [0, 10], faites simplement:
Le premier paramètre indique juste la taille du
IntStream
gé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:
Vous pouvez également le faire pour
double
et deslong
valeurs. J'espère que ça aide! :)la source
streamSize
- premier paramètre de cette méthode donnéstreamSize !=0
. Quelle est la différence sistreamSize
1/2 / n est donné?Vous pouvez modifier votre deuxième exemple de code pour:
la source
Une petite modification de votre première solution suffirait.
Voir plus ici pour la mise en œuvre de
Random
la source
ThreadLocalRandom
équivalent de classejava.util.Random
pour 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.x
,y
- intervalles par exemple (1,10)la source
La
Math.Random
classe en Java est basée sur 0. Donc, si vous écrivez quelque chose comme ça:x
sera entre0-9
inclus.Donc, étant donné le tableau d'
25
éléments suivant, le code pour générer un nombre aléatoire entre0
(la base du tableau) etarray.length
serait:Puisque
i.length
reviendra25
, lenextInt( i.length )
renverra un nombre entre la plage de0-24
. L'autre option va avecMath.Random
qui fonctionne de la même manière.Pour une meilleure compréhension, consultez le post du forum Intervalles aléatoires (archive.org) .
la source
index
variable 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.int index = rand.nextInt(i.Length);
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.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 atteindreInteger.MAX_VALUE
.(max - min)
peut provoquer un débordement lorsqu'ilmin
est négatif.Une solution infaillible retournerait des résultats corrects pour tout
min <= max
dans [Integer.MIN_VALUE
,Integer.MAX_VALUE
]. Considérez l'implémentation naïve suivante:Bien qu'inefficace, notez que la probabilité de succès dans la
while
boucle sera toujours de 50% ou plus.la source
Cela peut être fait en faisant simplement la déclaration:
Voici son code source
Randomizer.java
C'est juste propre et simple.
la source
Je me demande si l'une des méthodes de génération de nombres aléatoires fournies par une bibliothèque de mathématiques Apache Commons conviendrait.
Par exemple:
RandomDataGenerator.nextInt
ouRandomDataGenerator.nextLong
la source
Prenons un exemple.
Supposons que je souhaite générer un nombre compris entre 5 et 10 :
Comprenons cela ...
la source
la source
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:
la source
J'utilise ceci:
Vous pouvez le convertir en entier si vous le souhaitez.
la source
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 estInteger.MAX_VALUE
; la sortie dépend évidemment de l'entrée que vous n'avez pas spécifiée.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
SplittableRandom
qui 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
int
dans la plage[0, 1_000]:
Pour générer un
int[100]
tableau aléatoire de valeurs dans la plage[0, 1_000]:
Pour renvoyer un flux de valeurs aléatoires:
la source
.parallel()
? Il me semble que générer 100 nombres aléatoires serait trop trivial pour justifier le parallélisme.parallel
traitement). Soit dit en passant, pour un tableau d'1_000_000
éléments, laparallel
version était 2 fois plus rapide sur ma machine par rapport au séquentiel.Utilisez simplement la classe Random :
la source
Ces méthodes peuvent être pratiques à utiliser:
Cette méthode renverra un nombre aléatoire entre la valeur min et max fournie:
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):
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.min + 1
sera deux fois plus probable que l'autre résultatgetRandomNumberBetween
!En cas de lancer un dé, ce serait un nombre aléatoire compris entre 1 et 6 (pas entre 0 et 6), donc:
la source
Ou jetez un œil à RandomUtils d' Apache Commons .
la source
Double.valueOf(Math.random()*(maximum-minimun)).intValue()
est une façon assez obscure (et inefficace) de dire(int)(Math.random()*(maximum-minimun))
…Voici une classe utile pour générer au hasard
ints
dans une plage avec n'importe quelle combinaison de limites inclusives / exclusives:la source
Pour générer un nombre aléatoire "entre deux nombres", utilisez le code suivant:
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.
la source
Vous pouvez y parvenir de manière concise en Java 8:
la source
la source
Une autre option utilise simplement Apache Commons :
la source
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.
Un exemple d'exécution de cette classe:
la source
Il vaut mieux utiliser SecureRandom plutôt que simplement Random.
la source
private static int SecureRandom rand = new SecureRandom();
2:static {
3:rand.setSeed(...);
4:}
SecureRandom
, il sera semé par le système. L'appel directsetSeed
est très dangereux, il peut remplacer la graine (vraiment aléatoire) par la date. Et cela n'aboutira certainement pas à unSecureRandom
, car tout le monde peut deviner le temps et essayer de semer sa propreSecureRandom
instance avec ces informations.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.class
méthodes au même endroitExemple de résultats:
Sources:
la source
Cela fonctionne bien.
la source