Hoe genereer ik een willekeurige int
waarde in een specifiek bereik?
Ik heb het volgende geprobeerd, maar dat werkt niet:
Poging 1:
randomNum = minimum + (int)(Math.random() * maximum);
Bug: randomNum
kan groter zijn dan maximum
.
Poging 2:
Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum = minimum + i;
Bug: randomNum
kan kleiner zijn dan minimum
.
Antwoord 1, autoriteit 100%
In Java 1.7 of hoger is de standaardmanier 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 expliciet nodig is om een java.util.Random instantie, die bij onjuist gebruik een bron van verwarring en fouten kan zijn.
Omgekeerd is er echter geen manier om de seed expliciet in te stellen, dus het kan moeilijk zijn om resultaten te reproduceren in situaties waarin dat nuttig is, zoals het testen of opslaan van gamestatussen of iets dergelijks. In die situaties kan de hieronder getoonde 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 java De klasse .util.Random heeft vaak de voorkeur 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 als er een eenvoudige API in de standaardbibliotheek is om de taak te volbrengen.
Antwoord 2, autoriteit 36%
Merk op dat deze benadering meer bevooroordeeld en minder efficiënt is dan een nextInt
-benadering, https://stackoverflow .com/a/738651/360211
Een standaardpatroon om dit te bereiken is:
Min + (int)(Math.random() * ((Max - Min) + 1))
De Java Wiskundige bibliotheekfunctie Math.random() genereert een dubbele waarde in het bereik [0,1)
. Merk op dat dit bereik niet de 1 bevat.
Om eerst een specifiek waardenbereik te krijgen, moet u vermenigvuldigen met de grootte van het waardenbereik dat u wilt bestrijken.
Math.random() * ( Max - Min )
Dit retourneert een waarde in het bereik [0,Max-Min)
, waarbij ‘Max-Min’ niet is opgenomen.
Als u bijvoorbeeld [5,10)
wilt, moet u vijf gehele getallen afdekken, zodat u
Math.random() * 5
Dit zou een waarde in het bereik [0,5)
opleveren, waarbij 5 niet is inbegrepen.
Nu moet u dit bereik verschuiven naar het bereik waarop u zich richt. Dit doe je door de Min-waarde toe te voegen.
Min + (Math.random() * (Max - Min))
Je krijgt nu een waarde in het bereik [Min,Max)
. In navolging van ons voorbeeld betekent dat [5,10)
:
5 + (Math.random() * (10 - 5))
Maar dit is nog steeds niet inclusief Max
en je krijgt een dubbele waarde. Om de waarde Max
op te nemen, moet u 1 toevoegen aan uw bereikparameter (max - min)
en vervolgens het decimale deel afkappen door naar een int te casten. Dit wordt bereikt via:
Min + (int)(Math.random() * ((Max - Min) + 1))
En daar heb je het. Een willekeurig geheel getal in het bereik [Min,Max]
, of volgens het voorbeeld [5,10]
:
5 + (int)(Math.random() * ((10 - 5) + 1))
Antwoord 3, autoriteit 10%
Gebruik:
Random ran = new Random();
int x = ran.nextInt(6) + 5;
Het gehele getal x
is nu het willekeurige getal met een mogelijke uitkomst van 5-10
.
Antwoord 4, autoriteit 4%
Gebruik:
minimum + rn.nextInt(maxValue - minvalue + 1)
Antwoord 5, autoriteit 4%
Met java-8 ze introduceerden de methode ints(int randomNumberOrigin, int randomNumberBound)
in de Random
klasse.
Als u bijvoorbeeld vijf willekeurige gehele getallen (of één enkele) in het bereik [0, 10] wilt genereren, doet u het volgende:
Random r = new Random();
int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray();
int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt();
De eerste parameter geeft alleen de grootte aan van de gegenereerde IntStream
(wat de overbelaste methode is van degene die een onbeperkte IntStream
produceert).
Als u meerdere afzonderlijke oproepen moet doen, kunt u een oneindige primitieve iterator van de stream maken:
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();
}
}
Je kunt het ook doen voor double
en long
waarden. Ik hoop dat het helpt! 🙂
Antwoord 6, autoriteit 3%
U kunt uw tweede codevoorbeeld bewerken om:
Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum = rn.nextInt(range) + minimum;
Antwoord 7, autoriteit 3%
Een kleine wijziging van uw eerste oplossing zou voldoende zijn.
Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);
Zie hier meer voor de implementatie van Random
Antwoord 8, autoriteit 2%
ThreadLocalRandom
equivalent van klasse java.util.Random
voor multithreaded-omgevingen. Het genereren van een willekeurig getal wordt lokaal in elk van de threads uitgevoerd. We presteren dus beter door de conflicten te verminderen.
int rand = ThreadLocalRandom.current().nextInt(x,y);
x
,y
– intervallen b.v. (1,10)
Antwoord 9, autoriteit 2%
De klasse Math.Random
in Java is gebaseerd op 0. Dus, als je zoiets schrijft:
Random rand = new Random();
int x = rand.nextInt(10);
x
ligt tussen 0-9
inclusief.
Dus, gegeven de volgende array van 25
items, de code om een willekeurig getal te genereren tussen 0
(de basis van de array) en array.length
zou zijn:
String[] i = new String[25];
Random rand = new Random();
int index = 0;
index = rand.nextInt( i.length );
Aangezien i.length
25
retourneert, retourneert de nextInt( i.length )
een getal tussen het bereik van 0-24
. De andere optie gaat met Math.Random
die op dezelfde manier werkt.
index = (int) Math.floor(Math.random() * i.length);
Voor een beter begrip, bekijk de forumpost Willekeurige intervallen (archive.org).
Antwoord 10
Het kan gedaan worden door simpelweg de volgende instructie uit te voeren:
Randomizer.generate(0,10); //min of zero, max of ten
Hieronder staat de broncode
Randomizer.java
public class Randomizer {
public static int generate(int min,int max) {
return min + (int)(Math.random() * ((max - min) + 1));
}
}
Het is gewoon schoon en eenvoudig.
Antwoord 11
Vergeef me dat ik kieskeurig ben, maar de oplossing die door de meerderheid wordt voorgesteld, namelijk min + rng.nextInt(max - min + 1))
, lijkt gevaarlijk vanwege het feit dat:
rng.nextInt(n)
kanInteger.MAX_VALUE
niet bereiken.(max - min)
kan overflow veroorzaken wanneermin
negatief is.
Een onfeilbare oplossing zou correcte resultaten opleveren voor elke min <= max
binnen [Integer.MIN_VALUE
, Integer.MAX_VALUE
]. Overweeg de volgende naïeve implementatie:
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;
}
Hoewel inefficiënt, houd er rekening mee dat de kans op succes in de while
-lus altijd 50% of hoger zal zijn.
Antwoord 12
Ik vraag me af of een van de methoden voor het genereren van willekeurige getallen die door een Apache Commons Math bibliotheek zou passen.
Bijvoorbeeld: RandomDataGenerator.nextInt
of RandomDataGenerator.nextLong
Antwoord 13
Ik gebruik dit:
/**
* @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;
}
Je kunt het naar een geheel getal casten als je wilt.
Antwoord 14
Laten we een voorbeeld nemen.
Stel dat ik een getal tussen 5-10 wil genereren:
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);
Laat ons dit begrijpen…
Initialiseer max met de hoogste waarde en min met de laagste waarde.
Nu moeten we bepalen hoeveel mogelijke waarden kunnen worden verkregen. Voor dit voorbeeld zou het zijn:
5, 6, 7, 8, 9, 10
Dus de telling hiervan zou max – min + 1 zijn.
d.w.z. 10 – 5 + 1 = 6
Het willekeurige getal genereert een getal tussen 0-5.
d.w.z. 0, 1, 2, 3, 4, 5
Het toevoegen van de min waarde aan het willekeurige getal zou het volgende opleveren:
5, 6, 7, 8, 9, 10
Hierdoor verkrijgen we het gewenste bereik.
Antwoord 15
rand.nextInt((max+1) - min) + min;
Antwoord 16
Vanaf Java 7 mag u
Random
niet langer gebruiken. Voor de meeste toepassingen is de
willekeurige nummergenerator naar keuze is nu
ThreadLocalRandom
.Voor fork join pools en parallel
streams, gebruikSplittableRandom
.
Jozua Bloch. Effectieve Java. Derde editie.
Vanaf Java 8
Gebruik voor fork-join-pools en parallelle streams SplittableRandom
dat meestal sneller is, betere statistische onafhankelijkheid en uniformiteitseigenschappen heeft in vergelijking met Random
.
Een willekeurige int
genereren in het bereik [0, 1_000]:
int n = new SplittableRandom().nextInt(0, 1_001);
Een willekeurige reeks int[100]
met waarden in het bereik [0, 1_000]:
int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray();
Een stroom van willekeurige waarden retourneren:
IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
Antwoord 17
Genereer een willekeurig getal voor het verschil van min en max met behulp van de nextint(n) methode en voeg dan min nummer toe aan het resultaat:
Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
Antwoord 18
Gebruik gewoon de klasse Random:
Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
Antwoord 19
Gebruik de volgende code om een willekeurig getal “tussen twee getallen” te genereren:
Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;
Dit geeft u een willekeurig getal tussen 1 (inclusief) en 11 (exclusief), dus initialiseer de waarde voor de bovengrens door 1 toe te voegen. Als u bijvoorbeeld een willekeurig getal tussen 1 en 10 wilt genereren, initialiseert u het bovengrensnummer met 11 in plaats van 10.
Antwoord 20
Deze methode kan handig zijn om te gebruiken:
Deze methode retourneert een willekeurig getal tussen de opgegeven minimum- en maximumwaarde:
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;
}
}
en deze methode retourneert een willekeurig getal van de opgegeven min en max waarde (dus het gegenereerde getal kan ook het min of max getal zijn):
public static int getRandomNumberFrom(int min, int max) {
Random foo = new Random();
int randomNumber = foo.nextInt((max + 1) - min) + min;
return randomNumber;
}
Antwoord 21
In het geval van het gooien van een dobbelsteen zou het een willekeurig getal zijn tussen 1 en 6 (niet 0 tot 6), dus:
face = 1 + randomNumbers.nextInt(6);
Antwoord 22
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();
Of bekijk RandomUtils van Apache Commons.
Antwoord 23
Hier is een handige klasse om willekeurige ints
te genereren in een bereik met elke combinatie van inclusieve/exclusieve grenzen:
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;
}
}
Antwoord 24
Dat kun je op een beknopte manier bereiken in Java 8:
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);
Antwoord 25
Een andere optie is gewoon het gebruik van 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);
// ...
}
Antwoord 26
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);
}
Antwoord 27
Ik vond dit voorbeeld Willekeurige getallen genereren :
Dit voorbeeld genereert willekeurige gehele getallen in een specifiek bereik.
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);
}
}
Een voorbeeld van deze 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.
Antwoord 28
rand.nextInt((max+1) - min) + min;
Dit werkt prima.
Antwoord 29
Het is beter om SecureRandom te gebruiken dan alleen willekeurig.
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;
}
Antwoord 30
Hier is een eenvoudig voorbeeld dat laat zien hoe u een willekeurig getal genereert uit een gesloten [min, max]
-bereik, terwijl min <= max is true
Je kunt het hergebruiken als veld in hole class, waarbij je ook alle Random.class
methoden op één plek hebt staan
Resultatenvoorbeeld:
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
Bronnen:
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;
}
}