Jak wygenerować losowe liczby całkowite w określonym zakresie w Javie?

3500

Jak wygenerować losową intwartość w określonym zakresie?

Próbowałem następujące, ale te nie działają:

Próba 1:

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

Próba 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`.
użytkownik42155
źródło
Kiedy potrzebujesz wielu liczb losowych, nie polecam klasy Random w API. Ma za krótki okres. Zamiast tego spróbuj twistera Mersenne . Istnieje implementacja Java .
raupach,
1
Zanim opublikujesz nową odpowiedź, zastanów się, czy istnieje już ponad 65 odpowiedzi na to pytanie. Upewnij się, że twoja odpowiedź zawiera informacje, których nie ma wśród odpowiedzi istniejących.
janniks

Odpowiedzi:

3797

W Javie 1.7 lub nowszej standardowy sposób to zrobić:

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

Zobacz odpowiedni JavaDoc . Zaletą tego podejścia jest to, że nie trzeba jawnie inicjować instancji java.util.Random , która może być źródłem nieporozumień i błędów, jeśli zostanie użyta niewłaściwie.

Jednak z drugiej strony nie ma sposobu, aby jawnie ustawić ziarno, więc może być trudno odtworzyć wyniki w sytuacjach, w których jest to przydatne, takich jak testowanie lub zapisywanie stanów gry lub podobne. W takich sytuacjach można zastosować technikę wcześniejszą niż Java 1.7.

W wersjach wcześniejszych niż Java 1.7 standardowy sposób to zrobić:

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

Zobacz odpowiedni JavaDoc . W praktyce klasa java.util.Random jest często lepsza niż java.lang.Math.random () .

W szczególności nie ma potrzeby ponownego tworzenia koła losowego generowania liczb całkowitych, gdy w standardowej bibliotece znajduje się prosty interfejs API do wykonania zadania.

Greg Case
źródło
43
W przypadku połączeń, gdzie maxwartość jest Integer.MAX_VALUEmożliwe jest przepełnienie, skutkuje powstaniem java.lang.IllegalArgumentException. Można spróbować z: randInt(0, Integer.MAX_VALUE). Ponadto, jeśli nextInt((max-min) + 1)zwraca najwyższą wartość (zakładam, że dość rzadką), czy nie przepełni się ponownie (zakładając, że min i max są wystarczająco wysokimi wartościami)? Jak radzić sobie z tego rodzaju sytuacjami?
Daniel
3
@MoisheLipsker To musi być tak, że nextLong nie przyjmuje limitu jako nextInteger
mmm
13
@leventov ThreadLocalRandomzostał dodany do Javy 2 i pół roku po zadaniu tego pytania. Zawsze uważałem, że zarządzanie instancją Random jest poza zakresem pytania.
Greg Case
6
W Androidzie Random rand = new Random ();
Webserveis,
5
@Webserveis Zostało to rozwiązane w komentarzach w przykładzie. Wersja krótka - nie powinieneś = new Random () dla każdego wywołania funkcji, w przeciwnym razie wyniki nie będą wystarczająco losowe w wielu przypadkach.
Greg Case
1421

Pamiętaj, że to podejście jest bardziej stronnicze i mniej wydajne niż nextIntpodejście, https://stackoverflow.com/a/738651/360211

Jednym standardowym wzorcem do osiągnięcia tego jest:

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

Funkcja biblioteczna Java Math Math.random () generuje podwójną wartość w zakresie [0,1). Zauważ, że ten zakres nie obejmuje 1.

Aby najpierw uzyskać określony zakres wartości, należy pomnożyć przez wielkość zakresu wartości, które chcesz uwzględnić.

Math.random() * ( Max - Min )

Zwraca wartość z zakresu [0,Max-Min), w którym nie jest uwzględnione „Max-Min”.

Na przykład, jeśli chcesz [5,10), musisz podać pięć wartości całkowitych, abyś mógł użyć

Math.random() * 5

Zwróciłoby to wartość z zakresu [0,5), w którym 5 nie jest uwzględnione.

Teraz musisz przesunąć ten zakres do zakresu, na który celujesz. Robisz to, dodając wartość Min.

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

Otrzymasz teraz wartość z zakresu [Min,Max). Idąc za naszym przykładem, oznacza to [5,10):

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

Ale to wciąż nie obejmuje Maxi dostajesz podwójną wartość. Aby uwzględnić Maxwartość, musisz dodać 1 do parametru zakresu, (Max - Min)a następnie skrócić część dziesiętną, rzutując na liczbę całkowitą. Odbywa się to poprzez:

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

I masz to. Losowa wartość całkowita w zakresie [Min,Max]lub na przykład [5,10]:

5 + (int)(Math.random() * ((10 - 5) + 1))
TJ_Fischer
źródło
82
Dokumentacja firmy Sun wyraźnie mówi, że lepiej jest użyć Random (), jeśli potrzebujesz int zamiast Math.random (), który daje podwójną wartość.
Lilian A. Moraru
6
To jest właściwie stronnicze w porównaniu do metod nextInt stackoverflow.com/a/738651/360211
weston
4
„Biased” w tym przypadku oznacza, że ​​po 2 ^ 53 egzekucjach niektóre numery miały średnio jedno dodatkowe okazje.
Głowonogi
378

Posługiwać się:

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

Liczba całkowita xjest teraz liczbą losową, z możliwym wynikiem 5-10.

Martijn Pieters
źródło
159

Posługiwać się:

minimum + rn.nextInt(maxValue - minvalue + 1)
krosenvold
źródło
137

Z wprowadzili metodę ints(int randomNumberOrigin, int randomNumberBound)w Randomklasie.

Na przykład, jeśli chcesz wygenerować pięć losowych liczb całkowitych (lub jedną) z zakresu [0, 10], po prostu wykonaj:

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

Pierwszy parametr wskazuje tylko rozmiar IntStreamwygenerowanego (który jest przeciążonym sposobem tego, który wytwarza nieograniczoną liczbę IntStream).

Jeśli potrzebujesz wykonać wiele osobnych wywołań, możesz utworzyć nieskończony prymitywny iterator ze strumienia:

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

Możesz to również zrobić dla doublei longwartości. Mam nadzieję, że to pomoże! :)

Alexis C.
źródło
1
Sugerowałbym, aby utworzyć instancję randomIterator tylko raz. Zobacz komentarz Grega Case'a na temat własnej odpowiedzi.
Naxos84
jeśli możesz, czy możesz wyjaśnić, jakie jest znaczenie streamSize- podano pierwszy parametr tej metody streamSize !=0. Jaka jest różnica, jeśli streamSizepodano 1/2 / n?
Erfan Ahmed,
104

Możesz edytować swój drugi przykład kodu, aby:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;
Bill jaszczurka
źródło
99

Wystarczy niewielka modyfikacja pierwszego rozwiązania.

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

Zobacz więcej tutaj na temat wdrażania Random

hexabunny
źródło
Dla minimum <= wartość <maksimum, zrobiłem to samo z Math: randomNum = minimum + (int) (Math.random () * (maximum-minimum)); ale casting nie jest naprawdę przyjemny;)
AxelH
Co najmniej 7 lat spóźniona duplikat odpowiedzi.
Maarten Bodewes
70

ThreadLocalRandomodpowiednik klasy java.util.Randomdla środowiska wielowątkowego. Generowanie liczby losowej odbywa się lokalnie w każdym wątku. Mamy więc lepszą wydajność, redukując konflikty.

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

x, y- interwały np. (1,10)

Andrzej
źródło
66

Math.RandomKlasa w Javie jest 0 oparte. Jeśli więc napiszesz coś takiego:

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

xbędzie między 0-9włącznie.

Biorąc pod uwagę następującą tablicę 25elementów, kod generujący losową liczbę pomiędzy 0(podstawą tablicy) i array.lengthpowinien wyglądać następująco:

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

index = rand.nextInt( i.length );

Ponieważ i.lengthpowróci 25, nextInt( i.length )zwróci liczbę między zakresem 0-24. Inna opcja dotyczy tego, Math.Randomktóry działa w ten sam sposób.

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

Aby lepiej zrozumieć, sprawdź post na forum Random Intervals (archive.org) .

Matt R.
źródło
+1 za link do zrzutu ekranu archiwum wayBackMachine, a twoja odpowiedź jest nadal przydatnym odniesieniem do uzyskania „losowych” ints w / w zakresie.
Tapper7
Zaskakuje
@CodeConfident indexZmienna nie wpłynie na wynik liczby losowej. Możesz go zainicjować w dowolny sposób, nie martwiąc się o zmianę wyniku. Mam nadzieję że to pomoże.
Matt R
Dokładnie ... jest całkowicie nieużywany. int index = rand.nextInt(i.Length);
Zainicjowałbym
Albo wcale. int index; \n index = rand...jeśli ktoś lubi deklaracje i zadania w różnych wierszach. Niektóre standardy kodowania są bardziej rygorystyczne (i bez wyraźnego celu) niż inne.
Mark Storer
49

Wybacz mi, że jestem wybredny, ale rozwiązanie sugerowane przez większość, tj. min + rng.nextInt(max - min + 1))Wydaje się niebezpieczne ze względu na to, że:

  • rng.nextInt(n)nie może dosięgnąć Integer.MAX_VALUE.
  • (max - min)może powodować przepełnienie, gdy minjest ujemne.

Niezawodne rozwiązanie zwróci prawidłowe wyniki dla dowolnego min <= maxw [ Integer.MIN_VALUE, Integer.MAX_VALUE]. Rozważ następującą naiwną implementację:

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

Chociaż nieefektywne, należy pamiętać, że prawdopodobieństwo sukcesu w whilepętli zawsze będzie wynosić 50% lub więcej.

Joel Sjöstrand
źródło
Dlaczego nie zgłosić wyjątku IllegalArgumentException, gdy różnica = Integer.MAX_VALUE? Wtedy nie potrzebujesz pętli while.
MP Korstanje
3
@mpkorstanje Ta implementacja została zaprojektowana do pracy z dowolnymi wartościami min <= max, nawet jeśli ich różnica jest równa lub większa niż MAX_VALUE. Uruchamianie pętli aż do sukcesu jest w tym przypadku częstym wzorcem, aby zagwarantować równomierny rozkład (jeśli podstawowe źródło losowości jest jednolite). Random.nextInt (int) robi to wewnętrznie, gdy argument nie jest potęgą 2.
Christian Semrau
44

Można to zrobić po prostu wykonując instrukcję:

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

Poniżej znajduje się jego kod źródłowy

Randomizer.java

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

To jest po prostu czyste i proste.

Abel Callejo
źródło
5
To mogła być edycja innego przykładu, teraz jest to rażąca kopia dla reputacji. Wskazanie „odpowiedzi z największą liczbą głosów” również nie jest bardzo bezpośrednie, może się zmienić.
Maarten Bodewes,
1
Zgadza się @MaartenBodewes. Kiedy napisałem tę odpowiedź, odpowiedź z największą liczbą głosów powyżej została napisana jako rozwiązanie podobne do algorytmu. Teraz powyższe rozwiązanie bardzo się zmieniło i teraz ta odpowiedź wyglądała jak kopia.
Abel Callejo
Naprawdę nie rozumiem, dlaczego tak fundamentalne fragmenty kodu nie są częścią standardowych bibliotek Java. Dlaczego muszę to zaimplementować?
Leevi L
31

Weźmy przykład.

Załóżmy, że chcę wygenerować liczbę między 5-10 :

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

Pozwól nam to zrozumieć ...

Zainicjuj maks. Z najwyższą wartością i min z najniższą wartością.

Teraz musimy ustalić, ile możliwych wartości można uzyskać. W tym przykładzie byłoby to:

5, 6, 7, 8, 9, 10

Tak więc policzenie tego wynosi max - min + 1.

tj. 10 - 5 + 1 = 6

Liczba losowa wygeneruje liczbę między 0-5 .

tj. 0, 1, 2, 3, 4, 5

Dodanie wartości minimalnej do liczby losowej spowodowałoby:

5, 6, 7, 8, 9, 10

W ten sposób uzyskujemy pożądany zakres.

Sunil Chawla
źródło
29
 rand.nextInt((max+1) - min) + min;
Michael Myers
źródło
26

Wygeneruj liczbę losową dla różnicy min i maks przy użyciu metody nextint (n) , a następnie dodaj liczbę minimalną do wyniku:

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);
gifpif
źródło
26

Używam tego:

 /**
   * @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śli chcesz, możesz rzucić go na liczbę całkowitą.

Szymon
źródło
Ta funkcja generuje ciągle tę samą liczbę. W moim przypadku było to: 2147483647
sokras
Niepowodzenie: masz funkcję, która wymaga podwójnego, a następnie wykonać +1? Jest to z pewnością sprzeczne z zasadą najmniejszego zaskoczenia. Co się stanie, jeśli użyjesz min = 0,1 i max = 0,2?
Maarten Bodewes
@sokras wywołuje metodę new Random(sprawdź JavaDoc): „Tworzy nowy generator liczb losowych. Ten konstruktor ustawia ziarno generatora liczb losowych na wartość, która prawdopodobnie różni się od jakiegokolwiek innego wywołania tego konstruktora.” Najprawdopodobniej może to wymagać użycia aktualnego czasu jako ziarna. Jeśli ten czas zajmie milisekundy, obecne komputery są wystarczająco szybkie, aby wygenerować tę samą liczbę. Ale poza tym 2147483647 jest Integer.MAX_VALUE; wynik zależy oczywiście od danych wejściowych, których nie określono.
Maarten Bodewes
W końcu znalazłem ten, który faktycznie działa
Jency
23

Począwszy od wersji Java 7, nie powinieneś już używać Random. W przypadku większości zastosowań jest teraz wybrany generator liczb losowych ThreadLocalRandom.

W przypadku pul złączeń wideł i strumieni równoległych użyj SplittableRandom.

Joshua Bloch. Skuteczna Java. Trzecia edycja.

Począwszy od Java 8

W przypadku pul złączeń wideł i strumieni równoległych użycie, SplittableRandomktóre jest zwykle szybsze, ma lepszą statystyczną niezależność i jednolitość w porównaniu z Random.

Aby wygenerować losową intw zakresie[0, 1_000]:

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

Aby wygenerować losową int[100]tablicę wartości z zakresu[0, 1_000]:

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

Aby zwrócić strumień losowych wartości:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
Oleksandr Pyrohov
źródło
Czy istnieje powód, dla którego przykład zawiera .parallel()? Wydaje mi się, że wygenerowanie 100 liczb losowych byłoby zbyt trywialne, aby uzasadnić paralelizm.
Johnbot,
@Johnbot Dzięki za komentarz, masz rację. Ale głównym powodem było pokazanie interfejsu API (oczywiście inteligentną ścieżką jest pomiar wydajności przed użyciem parallelprzetwarzania). Nawiasem mówiąc, dla tablicy 1_000_000elementów parallelwersja była 2 razy szybsza na moim komputerze w porównaniu z sekwencyjnym.
Oleksandr Pyrohov
21

Wystarczy użyć klasy Random :

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
Prof Mo
źródło
8
Nie widzę tu nic nowego, czego nie opublikowano w niezliczonych wcześniejszych postach.
Maarten Bodewes,
20

Te metody mogą być wygodne w użyciu:

Ta metoda zwróci losową liczbę między podaną wartością minimalną i maksymalną:

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

i ta metoda zwróci losową liczbę z podanej wartości minimalnej i maksymalnej (więc wygenerowana liczba może być również liczbą minimalną lub maksymalną):

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

    return randomNumber;
}
Luke Taylor
źródło
// Since the random number is between the min and max values, simply add 1. Dlaczego? Nie liczy się min? Zazwyczaj zakres wynosi [min, maks.), Gdzie min jest uwzględniony, a maks. Jest wykluczony. Błędna odpowiedź, odrzucona.
Maarten Bodewes
Dodano @MaartenBodewes +1, ponieważ getRandomNumberBetween generuje losową liczbę bez podanych punktów końcowych.
Luke Taylor
1
Liczba min + 1będzie dwa razy bardziej prawdopodobna niż druga liczba getRandomNumberBetween!
Lii
19

W przypadku rzutu kostką byłaby to liczba losowa od 1 do 6 (nie od 0 do 6), więc:

face = 1 + randomNumbers.nextInt(6);
sam
źródło
19
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();

Lub spójrz na RandomUtils z Apache Commons .

użytkownik2427
źródło
Jest to przydatne, ale strzeż się drobnej wady: sygnatury metod są takie: nextDouble (double startInclusive, double endInclusive), ale jeśli spojrzysz na metody, endInclusive powinien faktycznie być endExclusive.
zakmck
Double.valueOf(Math.random()*(maximum-minimun)).intValue()jest dość zaciemnionym (i nieefektywnym) sposobem na powiedzenie (int)(Math.random()*(maximum-minimun))
Holger
Niedopasowanie pisowni dla minimalnego minimalnego zwrotu + Double.valueOf (Math.random () * (maksimum - minimum)). IntValue ();
Hrishikesh Mishra
18

Oto przydatna klasa do generowania losowego intsw zakresie z dowolną kombinacją granic włączających / wyłączających:

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;
    }
}
Garrett Hall
źródło
18

Aby wygenerować liczbę losową „pomiędzy dwiema liczbami”, użyj następującego kodu:

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

Daje to liczbę losową z przedziału od 1 (włącznie) do 11 (wyłącznie), więc zainicjuj wartość upperBound, dodając 1. Na przykład, jeśli chcesz wygenerować liczbę losową od 1 do 10, zainicjuj górną liczbę od 11 zamiast 10

Lawakush Kurmi
źródło
18

Możesz to zwięźle osiągnąć w Javie 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);
Mulalo Madida
źródło
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);
}
AZ_
źródło
16

Inną opcją jest właśnie użycie 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);
    // ...
 }
gerardw
źródło
16

Znalazłem ten przykład Wygeneruj losowe liczby :


Ten przykład generuje losowe liczby całkowite w określonym zakresie.

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

Przykładowy przebieg tej klasy:

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.
Szpitale
źródło
14

Lepiej jest używać SecureRandom niż tylko Random.

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;
}
grep
źródło
1
Nie jest to aż tak dobre, ponieważ jeśli zostanie wykonane w tej samej mili sekundy, to otrzymasz ten sam numer, musisz umieścić inicjalizację rand i setSeet poza metodą.
maraca
Potrzebujesz nasion, tak, ale używając SecureRandom.
grep
Przykro mi, ale ten, który odrzucił prośbę o zmianę, nie ma pojęcia o programowaniu w Javie. To dobra sugestia, ale jest błędna, ponieważ jeśli zostanie wykonana w tej samej mili sekundy, da ten sam numer, a nie losowy.
maraca
Nigdzie nie można znaleźć właściwego rozwiązania, niewiele osób zna statyczne bloki inicjalizujące ... tego należy użyć, aby ustawić ziarno: 1: private static int SecureRandom rand = new SecureRandom();2: static {3: rand.setSeed(...);4:}
maraca
5
Nie ma absolutnie potrzeby wysiewu SecureRandom, zostanie on zaszczepiony przez system. Bezpośrednie wywoływanie setSeedjest bardzo niebezpieczne, może zastąpić (naprawdę losowe) ziarno datą. A to z pewnością nie spowoduje SecureRandom, ponieważ każdy może odgadnąć czas i spróbować zaszczepić własną SecureRandominstancję tą informacją.
Maarten Bodewes
13

Oto prosta próbka, która pokazuje, jak wygenerować liczbę losową z zamkniętego [min, max] zakresu, natomiastmin <= max is true

Możesz użyć go ponownie jako pola w klasie dziur, również mając wszystko Random.class metody w jednym miejscu

Przykład wyników:

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

Źródła:

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;
    }
}
Jakow Mospan
źródło
13
rand.nextInt((max+1) - min) + min;

To działa dobrze.

ganesh
źródło