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


3505

Wie generiere ich einen zufälligen intWert in einem bestimmten Bereich?

Ich habe folgendes versucht, aber diese funktionieren 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`.

Wenn Sie viele Zufallszahlen benötigen, empfehle ich die Zufallsklasse in der API nicht. Es ist einfach zu kurz. Probieren Sie stattdessen den Mersenne-Twister . Es gibt eine Java-Implementierung .
Raupach

1
Bevor Sie eine neue Antwort veröffentlichen, sollten Sie berücksichtigen, dass diese Frage bereits über 65 Antworten enthält. Stellen Sie sicher, dass Ihre Antwort Informationen enthält, die nicht zu den vorhandenen Antworten gehören.
Janniks

Antworten:


3800

In Java 1.7 oder höher lautet die Standardmethode hierfür:

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 das entsprechende JavaDoc . Dieser Ansatz hat den Vorteil, dass eine java.util.Random- Instanz nicht explizit initialisiert werden muss. Dies kann bei unsachgemäßer Verwendung zu Verwirrung und Fehlern führen.

Umgekehrt gibt es jedoch keine Möglichkeit, den Startwert explizit festzulegen, sodass es schwierig sein kann, Ergebnisse in Situationen zu reproduzieren, in denen dies nützlich ist, z. B. beim Testen oder Speichern von Spielzuständen oder ähnlichem. In diesen Situationen kann die unten gezeigte Technik vor Java 1.7 verwendet werden.

Vor Java 1.7 ist dies standardmäßig 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 das entsprechende JavaDoc . In der Praxis ist die Klasse java.util.Random häufig java.lang.Math.random () vorzuziehen .

Insbesondere muss das Zufallsgenerierungsrad nicht neu erfunden werden, wenn die Standardbibliothek eine einfache API enthält, um die Aufgabe auszuführen.


43
Bei Anrufen, bei denen der maxWert angegeben ist Integer.MAX_VALUE, kann ein Überlauf auftreten, der zu a führt java.lang.IllegalArgumentException. Sie können versuchen mit : randInt(0, Integer.MAX_VALUE). Wenn nextInt((max-min) + 1)der höchste Wert zurückgegeben wird (ich nehme an, ziemlich selten), läuft er dann nicht wieder über (vorausgesetzt, min und max sind hoch genug)? Wie gehe ich mit solchen Situationen um?
Daniel

3
@MoisheLipsker Es muss sein, dass nextLong keine Grenze als nextInteger nimmt
mmm

13
@leventov ThreadLocalRandomwurde 2 1/2 Jahre nach der ersten Beantwortung dieser Frage zu Java hinzugefügt. Ich war immer der festen Meinung, dass die Verwaltung der Zufallsinstanz außerhalb des Rahmens der Frage liegt.
Greg Case

6
In Android Random rand = new Random ();
Webserveis

5
@Webserveis Dies wird in den Kommentaren im Beispiel angesprochen. Kurzversion - Sie sollten nicht bei jedem Aufruf der Funktion = new Random () verwenden, da Ihre Ergebnisse sonst in vielen Fällen nicht zufällig genug sind.
Greg Case

1422

Beachten Sie, dass dieser Ansatz voreingenommener und weniger effizient ist als der nextIntAnsatz https://stackoverflow.com/a/738651/360211

Ein Standardmuster, um dies zu erreichen, ist:

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

Die Java Math-Bibliotheksfunktion Math.random () generiert einen doppelten Wert im Bereich [0,1). Beachten Sie, dass dieser Bereich die 1 nicht enthält.

Um zuerst einen bestimmten Wertebereich zu erhalten, müssen Sie mit der Größe des Wertebereichs multiplizieren, den Sie abdecken möchten.

Math.random() * ( Max - Min )

Dies gibt einen Wert im Bereich zurück [0,Max-Min), in dem 'Max-Min' nicht enthalten ist.

Wenn Sie beispielsweise möchten [5,10), müssen Sie fünf ganzzahlige Werte abdecken, damit Sie sie verwenden können

Math.random() * 5

Dies würde einen Wert im Bereich zurückgeben [0,5), in dem 5 nicht enthalten ist.

Jetzt müssen Sie diesen Bereich auf den Bereich verschieben, auf den Sie abzielen. Sie tun dies, indem Sie den Min-Wert hinzufügen.

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

Sie erhalten nun einen Wert im Bereich [Min,Max). Nach unserem Beispiel bedeutet das [5,10):

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

Dies ist jedoch immer noch nicht enthalten Maxund Sie erhalten einen doppelten Wert. Um den MaxWert aufzunehmen, müssen Sie Ihrem Bereichsparameter 1 hinzufügen (Max - Min)und dann den Dezimalteil abschneiden, indem Sie ihn in ein int umwandeln. Dies erfolgt über:

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

Und da hast du es. Ein zufälliger ganzzahliger Wert im Bereich [Min,Max]oder gemäß dem Beispiel [5,10]:

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

82
In der Sun-Dokumentation heißt es ausdrücklich, dass Sie Random () besser verwenden sollten, wenn Sie ein int anstelle von Math.random () benötigen, das ein Double erzeugt.
Lilian A. Moraru

6
Dies ist tatsächlich voreingenommen im Vergleich zu nextInt Methoden stackoverflow.com/a/738651/360211
Weston

4
"Voreingenommen" bedeutet in diesem Fall, dass nach 2 ^ 53 Hinrichtungen einige Zahlen durchschnittlich ein zusätzliches Vorkommen hatten.
Kopffüßer

378

Verwenden:

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

Die Ganzzahl xist jetzt die Zufallszahl, deren Ergebnis möglicherweise ist 5-10.



137

Mit Sie führten die Methode ints(int randomNumberOrigin, int randomNumberBound)in der RandomKlasse ein.

Wenn Sie beispielsweise fünf zufällige Ganzzahlen (oder eine einzelne) im Bereich [0, 10] generieren möchten, gehen Sie einfach wie folgt vor:

Random r = new Random();
int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray();
int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt();

Der erste Parameter gibt nur die Größe des IntStreamgenerierten Parameters an (dies ist die überladene Methode derjenigen, die eine unbegrenzte erzeugt IntStream).

Wenn Sie mehrere separate Aufrufe ausführen müssen, können Sie aus dem Stream einen unendlichen primitiven Iterator erstellen:

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

Sie können dies auch für doubleund longWerte tun . Ich hoffe, es hilft! :) :)


1
Ich würde vorschlagen, dass Sie den randomIterator nur einmal instanziieren. Siehe Greg Case Kommentar zu seiner eigenen Antwort.
Naxos84

Wenn Sie dürfen, können Sie erklären, welche Bedeutung streamSizeder erste Parameter dieser Methode hat streamSize !=0. Was ist der Unterschied, wenn streamSize1/2 / n gegeben ist?
Erfan Ahmed

104

Sie können Ihr zweites Codebeispiel wie folgt bearbeiten:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;

100

Nur eine kleine Modifikation Ihrer ersten Lösung würde ausreichen.

Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);

Weitere Informationen zur Implementierung von finden Sie hier Random


Für Minimum <= Wert <Maximum habe ich dasselbe mit Math gemacht: randomNum = Minimum + (int) (Math.random () * (Maximum-Minimum)); aber das Casting ist nicht wirklich schön zu sehen;)
AxelH

Mindestens 7 Jahre verspätete doppelte Antwort.
Maarten Bodewes

70

ThreadLocalRandomÄquivalent der Klasse java.util.Randomfür eine Multithread-Umgebung. Das Generieren einer Zufallszahl erfolgt lokal in jedem der Threads. Wir haben also eine bessere Leistung, indem wir die Konflikte reduzieren.

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

x, y- Intervalle zB (1,10)


66

Die Math.RandomKlasse in Java basiert auf 0. Also, wenn Sie so etwas schreiben:

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

x wird zwischen sein 0-9 inklusive sein.

Bei dem folgenden Array von 25Elementen lautet der Code zum Generieren einer Zufallszahl zwischen 0(der Basis des Arrays) und array.length:

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

index = rand.nextInt( i.length );

Da i.lengthwird zurückgegeben 25, nextInt( i.length )wird der eine Zahl zwischen dem Bereich von zurückgeben 0-24. Die andere Option Math.Randomfunktioniert genauso.

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

Weitere Informationen finden Sie im Forum-Beitrag Zufällige Intervalle (archive.org) .


+1 für den WayBackMachine-Archiv-Screenshot-Link & Ihre Antwort ist immer noch eine nützliche Referenz, um "zufällige" Ints mit einem Bereich zu erhalten.
Tapper7

Es verwirrt mich, warum Sie den Index auf 0 instanziieren.
AjahnCharles

@CodeConfident Die indexVariable hat keinen Einfluss auf das Ergebnis der Zufallszahl. Sie können es nach Belieben initialisieren, ohne sich Gedanken über die Änderung des Ergebnisses machen zu müssen. Hoffe das hilft.
Matt R

Genau ... es ist völlig unbenutzt. Ich würde es direkt auf den Rand initialisieren:int index = rand.nextInt(i.Length);
AjahnCharles

Oder gar nicht. int index; \n index = rand...wenn man Erklärungen und Aufgaben in verschiedenen Zeilen mag. Einige Codierungsstandards sind strenger (und ohne offensichtlichen Zweck) als andere.
Mark Storer

49

Verzeihen Sie mir, dass ich anspruchsvoll bin, aber die von der Mehrheit vorgeschlagene Lösung, dh min + rng.nextInt(max - min + 1)), scheint gefährlich zu sein, weil:

  • rng.nextInt(n)kann nicht erreichen Integer.MAX_VALUE.
  • (max - min)kann einen Überlauf verursachen, wenn er minnegativ ist.

Eine narrensichere Lösung würde korrekte Ergebnisse für alle min <= maxinnerhalb von [ Integer.MIN_VALUE, Integer.MAX_VALUE] zurückgeben. Betrachten Sie die folgende naive Implementierung:

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

Beachten Sie, dass die Erfolgswahrscheinlichkeit in der whileSchleife immer 50% oder mehr beträgt, obwohl sie ineffizient ist .


Warum nicht eine IllegalArgumentException auslösen, wenn der Unterschied = Integer.MAX_VALUE ist? Dann brauchen Sie die while-Schleife nicht.
MP Korstanje

3
@mpkorstanje Diese Implementierung ist so konzipiert, dass sie mit allen Werten von min <= max funktioniert, auch wenn ihre Differenz gleich oder sogar größer als MAX_VALUE ist. Das Ausführen einer Schleife bis zum Erfolg ist in diesem Fall ein gängiges Muster, um eine gleichmäßige Verteilung zu gewährleisten (wenn die zugrunde liegende Zufallsquelle gleichmäßig ist). Random.nextInt (int) macht es intern, wenn das Argument keine Potenz von 2 ist.
Christian Semrau

44

Dies kann durch einfaches Ausführen der folgenden Anweisung erfolgen:

Randomizer.generate(0,10); //min of zero, max of ten

Unten ist der Quellcode

Randomizer.java

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

Es ist einfach sauber und einfach.


5
Dies könnte eine Bearbeitung des anderen Beispiels gewesen sein, jetzt ist es nur eine eklatante Kopie für den Ruf. Es ist auch nicht sehr direkt, auf die "Antwort mit den meisten Stimmen" hinzuweisen, sie kann sich ändern.
Maarten Bodewes

1
Das ist richtig @MaartenBodewes. Als ich diese Antwort schrieb, wurde die Antwort mit den meisten Stimmen oben immer noch als algorithmische Lösung geschrieben. Jetzt hat sich die obige Lösung sehr verändert und jetzt sah diese Antwort wie eine Nachahmerin aus.
Abel Callejo

Ich verstehe wirklich nicht, warum solche grundlegenden Codebits nicht Teil von Java-Standardbibliotheken sind. Warum muss ich das implementieren?
Leevi L


31

Nehmen wir ein Beispiel.

Angenommen, ich möchte eine Zahl zwischen 5 und 10 generieren :

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

Lassen Sie uns das verstehen ...

Initialisieren Sie max mit dem höchsten Wert und min mit dem niedrigsten Wert.

Nun müssen wir bestimmen, wie viele mögliche Werte erhalten werden können. Für dieses Beispiel wäre es:

5, 6, 7, 8, 9, 10

Die Anzahl wäre also max - min + 1.

dh 10 - 5 + 1 = 6

Die Zufallszahl erzeugt eine Zahl zwischen 0 und 5 .

dh 0, 1, 2, 3, 4, 5

Das Hinzufügen des Min- Werts zur Zufallszahl würde Folgendes ergeben:

5, 6, 7, 8, 9, 10

Somit erhalten wir den gewünschten Bereich.



26

Generieren Sie eine Zufallszahl für die Differenz von min und max mithilfe der nextint (n) -Methode und fügen Sie dann dem Ergebnis eine min-Zahl hinzu:

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);

26

Ich benutze das:

 /**
   * @param min - The minimum.
   * @param max - The maximum.
   * @return A random double between these numbers (inclusive the minimum and maximum).
   */
 public static double getRandom(double min, double max) {
   return (Math.random() * (max + 1 - min)) + min;
 }

Sie können es in eine Ganzzahl umwandeln, wenn Sie möchten.


Diese Funktion erzeugt immer wieder dieselbe Nummer. In meinem Fall war es: 2147483647
sokras

Fehler: Sie haben eine Funktion, die ein Double erfordert und dann + 1 ausführt? Dies widerspricht sicherlich dem Prinzip der geringsten Überraschung. Was passiert, wenn Sie min = 0,1 und max = 0,2 verwenden?
Maarten Bodewes

@sokras ruft die Methode auf new Random(überprüfen Sie das JavaDoc): "Erstellt einen neuen Zufallszahlengenerator. Dieser Konstruktor setzt den Startwert des Zufallszahlengenerators auf einen Wert, der sich sehr wahrscheinlich von jedem anderen Aufruf dieses Konstruktors unterscheidet." Sehr wahrscheinlich wird nur die aktuelle Zeit als Startwert verwendet. Wenn diese Zeit Millisekunden benötigt, sind die aktuellen Computer schnell genug, um dieselbe Zahl zu generieren. Aber außerdem ist 2147483647 Integer.MAX_VALUE; Die Ausgabe hängt offensichtlich von der Eingabe ab, die Sie nicht angegeben haben.
Maarten Bodewes

Endlich die gefunden, die tatsächlich funktioniert
Jency

23

Ab Java 7 sollten Sie nicht mehr verwenden Random. Für die meisten Anwendungen ist jetzt der Zufallszahlengenerator der Wahl ThreadLocalRandom.

Verwenden Sie für Fork Join-Pools und parallele Streams SplittableRandom.

Joshua Bloch. Effektives Java. Dritte Edition.

Ab Java 8

Bei Fork-Join-Pools und parallelen Streams ist die Verwendung SplittableRandom, die normalerweise schneller ist, im Vergleich zu statistisch besser und einheitlicher Random.

Um einen Zufall intim Bereich zu generieren[0, 1_000]:

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

So generieren Sie ein zufälliges int[100]Array von Werten im Bereich[0, 1_000]:

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

So geben Sie einen Stream mit zufälligen Werten zurück:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);

Gibt es einen Grund, warum das Beispiel a enthält .parallel()? Es scheint mir, als wäre das Generieren von 100 Zufallszahlen zu trivial, um Parallelität zu rechtfertigen.
Johnbot

@ Johnbot Danke für den Kommentar, du hast recht. Der Hauptgrund war jedoch, eine API anzuzeigen (der intelligente Pfad besteht natürlich darin, die Leistung vor der Verwendung der parallelVerarbeitung zu messen ). Übrigens 1_000_000war die parallelVersion für eine Reihe von Elementen auf meinem Computer im Vergleich zur sequentiellen Version zweimal schneller.
Oleksandr Pyrohov

21

Verwenden Sie einfach die Zufallsklasse :

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);

8
Ich sehe hier nichts Neues, das in unzähligen früheren Beiträgen nicht veröffentlicht wurde.
Maarten Bodewes

20

Diese Methoden sind möglicherweise bequem zu verwenden:

Diese Methode gibt eine Zufallszahl zwischen dem angegebenen Min- und Max-Wert zurück:

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

und diese Methode gibt eine Zufallszahl aus dem angegebenen Min- und Max-Wert zurück (die generierte Zahl kann also auch die Min- oder Max-Zahl sein):

public static int getRandomNumberFrom(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt((max + 1) - min) + min;

    return randomNumber;
}

// Since the random number is between the min and max values, simply add 1. Warum? Zählt min nicht? Normalerweise ist der Bereich [min, max], wobei min eingeschlossen und max ausgeschlossen ist. Falsche Antwort, abgelehnt.
Maarten Bodewes

@MaartenBodewes +1 wird hinzugefügt, da getRandomNumberBetween eine Zufallszahl ohne die angegebenen Endpunkte generiert.
Luke Taylor

1
Die Zahl min + 1ist doppelt so wahrscheinlich wie die andere Zahl das Ergebnis von getRandomNumberBetween!
Lii

19

Im Falle eines Würfelns wäre es eine Zufallszahl zwischen 1 und 6 (nicht 0 bis 6), also:

face = 1 + randomNumbers.nextInt(6);

19
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();

Oder werfen Sie einen Blick auf RandomUtils von Apache Commons .


Das ist nützlich, aber Vorsicht vor einem kleinen Fehler: Methodensignaturen sind wie folgt: nextDouble (double startInclusive, double endInclusive), aber wenn Sie sich die Methoden ansehen, sollte endInclusive tatsächlich endExclusive sein.
Zakmck

Double.valueOf(Math.random()*(maximum-minimun)).intValue()ist eine ziemlich verschleierte (und ineffiziente) Art zu sagen (int)(Math.random()*(maximum-minimun))...
Holger

Rechtschreibfehlanpassung für minimale Rückgabe Minimum + Double.valueOf (Math.random () * (Maximum - Minimum)). IntValue ();
Hrishikesh Mishra

18

Hier ist eine hilfreiche Klasse, um Zufallszahlen intsin einem Bereich mit einer beliebigen Kombination von Inklusiv- / Exklusivgrenzen zu generieren :

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

Verwenden Sie den folgenden Code, um eine Zufallszahl "zwischen zwei Zahlen" zu generieren:

Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;

Dies gibt Ihnen eine Zufallszahl zwischen 1 (einschließlich) und 11 (exklusiv). Initialisieren Sie also den UpperBound-Wert durch Hinzufügen von 1. Wenn Sie beispielsweise eine Zufallszahl zwischen 1 und 10 generieren möchten, initialisieren Sie die UpperBound-Zahl mit 11 anstelle von 11 10.


18

Sie können dies in Java 8 präzise erreichen:

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

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

16

Eine andere Option ist nur die Verwendung von 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);
    // ...
 }

16

Ich habe dieses Beispiel gefunden. Zufallszahlen generieren :


In diesem Beispiel werden zufällige Ganzzahlen in einem bestimmten Bereich generiert.

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

Ein Beispiellauf dieser Klasse:

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.

14

Es ist besser, SecureRandom als nur Random zu verwenden.

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

1
Dies ist nicht so gut, denn wenn es in derselben Millisekunde ausgeführt wird, erhalten Sie dieselbe Nummer. Sie müssen die Rand-Initialisierung und das setSeet außerhalb der Methode platzieren.
Maraca

Sie brauchen Samen, ja, aber mit SecureRandom.
grep

Es tut mir leid, aber derjenige, der die Änderungsanforderung abgelehnt hat, hat keine Ahnung von der Java-Programmierung. Es ist ein guter Vorschlag, aber wie es falsch ist, weil es, wenn es in derselben Millisekunde ausgeführt wird, dieselbe Nummer gibt, nicht zufällig.
Maraca

Die richtige Lösung ist nirgends zu finden, nicht viele Leute kennen statische Initialisierungsblöcke ... das ist es, was Sie verwenden sollten, um den private static int SecureRandom rand = new SecureRandom();static {rand.setSeed(...);}
Startwert

5
Es besteht absolut keine Notwendigkeit zu säen SecureRandom, es wird vom System ausgesät. Direktes Anrufen setSeedist sehr gefährlich, es kann den (wirklich zufälligen) Startwert durch das Datum ersetzen. Und das wird sicherlich nicht zu einem Ergebnis führen SecureRandom, da jeder die Zeit erraten und versuchen kann, seine eigene SecureRandomInstanz mit diesen Informationen zu versehen.
Maarten Bodewes

13

Hier ist ein einfaches Beispiel, das zeigt, wie Zufallszahlen aus dem geschlossenen [min, max]Bereich generiert werdenmin <= max is true

Sie können es als Feld in der Lochklasse wiederverwenden und alle Random.classMethoden an einem Ort haben

Ergebnisbeispiel:

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

Quellen:

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

13
rand.nextInt((max+1) - min) + min;

Das funktioniert gut.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.