Wie generiere ich in Java zufällige Ganzzahlen innerhalb eines bestimmten Bereichs?

Wie generiere ich einen zufälligen int-Wert in einem bestimmten Bereich?

Ich habe Folgendes versucht, aber das funktioniert nicht:

Versuch 1:

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

Versuch 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 oder höher ist die Standardmethode hierfür wie folgt:

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

Siehe die entsprechende JavaDoc. Dieser Ansatz hat den Vorteil, dass eine java.util.Random-Instanz nicht explizit initialisiert werden muss, was bei unsachgemäßer Verwendung eine Quelle von Verwirrung und Fehlern sein kann.

Umgekehrt gibt es jedoch keine Möglichkeit, den Seed explizit zu setzen, so dass es in Situationen, in denen dies nützlich ist, wie z. B. beim Testen oder Speichern von Spielzuständen oder Ähnlichem, schwierig sein kann, Ergebnisse zu reproduzieren. In solchen Situationen kann die unten gezeigte Technik aus der Zeit vor Java 1.7 verwendet werden.

Vor Java 1.7 war die Standardmethode wie folgt:

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

Siehe die entsprechende JavaDoc. In der Praxis ist die Klasse java.util.Random oft besser geeignet als java.lang.Math.random().

Insbesondere besteht keine Notwendigkeit, das Rad der Zufallszahlengenerierung neu zu erfinden, wenn es eine unkomplizierte API innerhalb der Standardbibliothek gibt, um diese Aufgabe zu erfüllen.

Kommentare (18)

Verwendung:

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