Hvordan genererer jeg tilfældige heltal inden for et bestemt område i Java?

Hvordan genererer jeg en tilfældig int-værdi inden for et bestemt område?

Jeg har prøvet følgende, men de virker ikke:

Forsøg 1:

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

Forsøg 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`.

I Java 1.7 eller nyere er standardmetoden følgende:

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

Se den relevante JavaDoc. Denne fremgangsmåde har den fordel, at det ikke er nødvendigt at initialisere en java.util.Random-instans eksplicit, hvilket kan være en kilde til forvirring og fejl, hvis det bruges uhensigtsmæssigt.

Men omvendt er der ingen måde at sætte frøet eksplicit på, så det kan være svært at reproducere resultater i situationer, hvor det er nyttigt, f.eks. ved test eller lagring af spiltilstande eller lignende. I disse situationer kan den nedenfor viste teknik fra før Java 1.7 anvendes.

For Java 1.7 er standardmetoden følgende:

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

Se den relevante JavaDoc. I praksis er klassen java.util.Random ofte at foretrække frem for java.lang.Math.random().

Især er der ingen grund til at genopfinde hjulet til generering af tilfældige heltal på ny, når der findes en simpel API i standardbiblioteket til at udføre opgaven.

Kommentarer (18)

Anvendelse:

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