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

Comment puis-je générer une valeur aléatoire int dans une plage spécifique?

j'ai essayé les suivants, 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`.
2960
demandé sur Steve Chambers 2008-12-12 21:20:57

30 réponses

Dans Java 1.7 ou plus tard , le standard de la façon de le faire est comme suit:

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 à la JavaDoc . Cette approche a l'avantage de ne pas avoir besoin d'initialiser explicitement un java .util.Instance aléatoire , 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 afin qu'elle puisse être difficile de reproduire des résultats dans des situations où cela est utile, comme tester ou sauvegarder des états de jeu ou similaire. Dans ces situations, la technique pré-Java 1.7 présentée ci-dessous peut être utilisée.

avant Java 1.7 , la méthode standard 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 à la JavaDoc . En pratique, le java.util.La classe aléatoire est souvent préférable à de java.lang.Mathématique.random () .

en particulier, il n'est pas nécessaire de réinventer la roue de génération d'entier aléatoire quand il y a une API simple dans la bibliothèque standard pour accomplir la tâche.

3312
répondu Greg Case 2018-01-04 07:02:27

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

Un modèle standard pour la réalisation de ce est:

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

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

In afin d'obtenir une plage spécifique de valeurs d'abord, vous devez multiplier par l'ampleur de l'intervalle de valeurs que vous voulez couvrir.

Math.random() * ( Max - Min )

renvoie une valeur dans la gamme [0,Max-Min) , où "Max-Min" n'est pas inclus.

par exemple, si vous voulez [5,10) , vous devez couvrir cinq valeurs entières donc vous utilisez

Math.random() * 5

on obtiendrait ainsi une valeur dans la gamme [0,5) , où 5 n'est pas inclus.

maintenant vous devez déplacer cette gamme jusqu'à la gamme que vous ciblez. Vous faites cela en ajoutant la valeur Min.

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

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

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

mais, cela n'inclut toujours pas Max et vous obtenez une valeur double. Afin d'obtenir la valeur Max inclus, vous devez ajouter 1 à votre gamme paramètre (Max - Min) et puis tronquer la partie décimale en moulant à un int. Ceci est accompli via:

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

et voilà. Une valeur entière aléatoire dans la gamme [Min,Max] , ou par l'exemple [5,10] :

5 + (int)(Math.random() * ((10 - 5) + 1))
1343
répondu TJ_Fischer 2018-07-24 13:19:30

utiliser:

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

le nombre entier x est maintenant le nombre aléatoire qui a un résultat possible de 5-10 .

314
répondu Azeem 2018-04-23 05:19:53

utiliser:

minimum + rn.nextInt(maxValue - minvalue + 1)
126
répondu krosenvold 2014-06-22 22:22:52

avec ils ont introduit la méthode ints(int randomNumberOrigin, int randomNumberBound) dans la classe Random .

par exemple si vous voulez générer cinq entiers aléatoires (ou un seul) dans la gamme [0, 10], faites juste:

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 IntStream généré (qui est la méthode surchargée de celui qui produit un illimité IntStream ).

si vous devez faire plusieurs appels séparés, 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 les valeurs double et long .

Espère que cela aide! :)

102
répondu Alexis C. 2017-10-04 11:39:56

vous pouvez modifier votre deuxième exemple de code en:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;
91
répondu Bill the Lizard 2008-12-12 18:31:28

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

90
répondu hexabunny 2018-04-20 16:51:23

ThreadLocalRandom équivalent de la classe java.util.Aléatoire pour l'environnement multithread. Générer un nombre aléatoire est effectué localement dans chacun des threads. Si nous avons une meilleure performance en réduisant les conflits.

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

x,y - intervalles p.ex. (1,10)

57
répondu andrew 2016-04-21 06:03:42

la classe Math.Random dans Java est basée sur 0. Donc, si vous écrivez quelque chose comme ceci:

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

x se situera entre 0-9 inclusivement.

ainsi, étant donné le tableau suivant de 25 articles, le code pour générer un nombre aléatoire entre 0 (la base du tableau) et array.length serait:

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

index = rand.nextInt( i.length );

depuis i.length retournera 25 , le nextInt( i.length ) renverra un nombre compris entre 0-24 . L'autre option va avec Math.Random qui fonctionne de la même manière.

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

pour une meilleure compréhension, consultez l'article du forum intervalles aléatoires (archive.org) .

54
répondu Matt R 2018-04-23 05:19:23

Pardonnez-moi d'être fastidieux, mais la solution proposée par la majorité, i.e., min + rng.nextInt(max - min + 1)) , semble périlleuse en raison du fait que:

  • rng.nextInt(n) impossible d'atteindre Integer.MAX_VALUE .
  • (max - min) peut causer un débordement lorsque min est négatif.

une solution infaillible retournerait des résultats corrects pour n'importe quel min <= max dans [ Integer.MIN_VALUE , Integer.MAX_VALUE ]. Envisager l' suite à la mise en œuvre naïve:

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 boucle while sera toujours de 50% ou plus.

44
répondu Joel Sjöstrand 2018-04-23 05:21:33

je me demande si l'une des méthodes de génération de nombres aléatoires fournies par une bibliothèque Apache Commons Math conviendrait au projet de loi.

par exemple: RandomDataGenerator.nextInt ou RandomDataGenerator.nextLong

26
répondu Chinnery 2016-11-16 12:08:17

prenons un exemple.

supposons que je souhaite générer un nombre entre 5-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 ce ...

initialise 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, il serait:

5, 6, 7, 8, 9, 10

donc, compte de cela serait max - min + 1.

c'est à dire 10 - 5 + 1 = 6

le nombre aléatoire va générer un nombre entre 0-5 .

c'est à dire 0, 1, 2, 3, 4, 5

en ajoutant la valeur min au nombre aléatoire produirait:

5, 6, 7, 8, 9, 10

nous obtenons ainsi la portée désirée.

25
répondu Sunil Chawla 2018-04-26 20:14:06
 rand.nextInt((max+1) - min) + min;
22
répondu Michael Myers 2017-12-20 19:34:30

Voici une classe utile pour générer au hasard ints dans une gamme 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;
    }
}
18
répondu Garrett Hall 2012-02-15 16:19:03

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

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
18
répondu gifpif 2016-07-06 19:23:24

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

face = 1 + randomNumbers.nextInt(6);
17
répondu sam 2016-04-21 06:01:47

à partir de Java 7, vous ne devez plus utiliser Random . Pour la plupart des utilisations, le générateur de nombre aléatoire de choix est maintenant ThreadLocalRandom .



pour les pools de jonction de fourche et parallèle streams, utiliser SplittableRandom .

Joshua Bloch. Java Efficace. Troisième Édition.

à partir de Java 8

pour les pools de jonction de fourche et les flux parallèles, utilisez 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 int aléatoire dans la gamme [0, 1_000]:

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

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

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

pour retourner un ruisseau de valeurs aléatoires:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
17
répondu Oleksandr 2018-05-20 19:07:45
int random = minimum + Double.valueOf(Math.random()*(maximum-minimun)).intValue();

Ou de prendre un coup d'oeil à RandomUtils de Apache Commons .

16
répondu user2427 2014-06-22 22:23:28

cette méthode peut être commode à utiliser:

cette méthode retournera 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 retournera un nombre aléatoire de la valeur min et max fournie (Donc le nombre généré pourrait aussi ê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;
}
16
répondu Luke Taylor 2017-12-20 19:37:20

quand vous avez besoin de beaucoup de nombres aléatoires, Je ne recommande pas la classe aléatoire dans L'API. Il a juste une trop petite période. Essayez plutôt le Mersenne twister . Il y a une implémentation Java .

15
répondu raupach 2013-08-01 18:02:34
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);
}
15
répondu AZ_ 2013-08-01 18:25:39

j'ai trouvé cet exemple générer des nombres aléatoires :


cet exemple génère des nombres 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.
15
répondu Hospes 2017-12-20 19:35:57

vous pouvez réaliser que concisely 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);
15
répondu Mulalo Madida 2018-04-26 20:08:56

voici un échantillon simple qui montre comment générer un nombre aléatoire à partir de la gamme fermée [min, max] , tandis que min <= max is true

vous pouvez le réutiliser comme champ dans la classe de trou, ayant également toutes les méthodes Random.class en un seul 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;
    }
}
14
répondu Yakiv Mospan 2014-11-28 00:58:54

il suffit D'utiliser le aléatoire classe:

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
14
répondu Prof Mo 2016-04-21 06:04:49

une autre option est d'utiliser 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);
    // ...
 }
14
répondu gerardw 2018-04-23 05:22:28

si vous voulez essayer la réponse avec le plus de votes ci-dessus, vous pouvez simplement utiliser ce code:

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

    public static void main(String[] args)
    {
        System.out.println(Randomizer.generate(0,10));
    }
}

c'est juste propre et simple.

11
répondu Abel Callejo 2014-06-22 22:26:02
private static Random random = new Random();    

public static int getRandomInt(int min, int max){
  return random.nextInt(max - min + 1) + min;
}

ou

public static int getRandomInt(Random random, int min, int max)
{
  return random.nextInt(max - min + 1) + min;
}
11
répondu Muhammad Aamir Talib 2016-04-21 06:05:53

il est préférable d'utiliser SecureRandom plutôt que juste au hasard.

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;
}
11
répondu grep 2016-07-06 19:19:36
rand.nextInt((max+1) - min) + min;

ça marche très bien.

10
répondu ganesh 2016-04-21 06:01:59