Hoe genereer ik willekeurige gehele getallen binnen een bepaald bereik in Java?

Hoe genereer ik een willekeurige int waarde in een bepaald bereik?

Ik heb het volgende geprobeerd, maar dat werkt niet:

Probeer 1:

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

**Poging 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`.

In Java 1.7 of later, is de standaard manier om dit te doen als volgt:

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

Zie de relevante JavaDoc. Deze aanpak heeft het voordeel dat het niet nodig is om een java.util.Random instantie expliciet te initialiseren, wat een bron van verwarring en fouten kan zijn als het onjuist wordt gebruikt.

Omgekeerd is er echter geen manier om het zaad expliciet in te stellen, zodat het moeilijk kan zijn om resultaten te reproduceren in situaties waarin dat nuttig is, zoals testen of het opslaan van spelstatussen of iets dergelijks. In die situaties kan de onderstaande pre-Java 1.7 techniek worden gebruikt.

Vóór Java 1.7 is de standaardmanier om dit te doen als volgt:

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

Zie de relevante JavaDoc. In de praktijk is de klasse java.util.Random vaak te verkiezen boven java.lang.Math.random().

In het bijzonder is het niet nodig om het wiel voor het genereren van willekeurige gehele getallen opnieuw uit te vinden wanneer er een eenvoudige API binnen de standaardbibliotheek bestaat om deze taak uit te voeren.

Commentaren (18)

Gebruik:

minimum + rn.nextInt(maxValue - minvalue + 1)
Commentaren (0)
 rand.nextInt((max+1) - min) + min;
Commentaren (0)