Kako v Javi ustvarim naključna cela števila v določenem območju?

Kako ustvarim naključno vrednost int v določenem območju?

Poskusil sem z naslednjimi načini, vendar ti ne delujejo:

Poskus 1:

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

Kus 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`.

V Javi 1.7 ali novejši je standardni način za to naslednji:

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

Glej ustrezni dokument JavaDoc. Prednost tega pristopa je, da ni treba izrecno inicializirati instance java.util.Random, kar je lahko ob neustrezni uporabi vir zmede in napak.

Vendar pa nasprotno ni načina za izrecno nastavitev semena, zato je lahko težko reproducirati rezultate v primerih, ko je to koristno, na primer pri testiranju ali shranjevanju stanja igre in podobno. V teh primerih se lahko uporabi tehnika pred izdajo Jave 1.7, ki je prikazana spodaj.

Pred Javo 1.7 je bil standardni način izvedbe naslednji:

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

Glej ustrezni dokument JavaDoc. V praksi je razred java.util.Random pogosto boljši od java.lang.Math.random().

Zlasti ni treba na novo izumljati kolesa za generiranje naključnih celih števil, če je v standardni knjižnici na voljo enostaven API za izvedbo te naloge.

Komentarji (18)

Uporaba:

minimum + rn.nextInt(maxValue - minvalue + 1)
Komentarji (0)