Bagaimana cara menghasilkan bilangan bulat acak dalam rentang tertentu di Jawa?

3507

Bagaimana cara menghasilkan intnilai acak dalam rentang tertentu?

Saya sudah mencoba yang berikut ini, tetapi itu tidak berhasil:

Percobaan 1:

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

Percobaan 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`.
pengguna42155
sumber
Ketika Anda membutuhkan banyak angka acak, saya tidak merekomendasikan kelas acak di API. Ini memiliki periode yang terlalu kecil. Coba twister Mersenne sebagai gantinya. Ada implementasi Java .
raupach
1
Sebelum Anda memposting jawaban baru, pertimbangkan sudah ada 65+ jawaban untuk pertanyaan ini. Harap pastikan bahwa jawaban Anda menyumbangkan informasi yang tidak ada di antara jawaban yang ada.
janniks

Jawaban:

3802

Di Jawa 1.7 atau lebih baru , cara standar untuk melakukan ini adalah sebagai berikut:

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

Lihat JavaDoc yang relevan . Pendekatan ini memiliki keuntungan karena tidak perlu menginisialisasi secara eksplisit contoh java.util.Random , yang dapat menjadi sumber kebingungan dan kesalahan jika digunakan secara tidak tepat.

Namun, sebaliknya tidak ada cara untuk mengatur benih secara eksplisit sehingga sulit untuk mereproduksi hasil dalam situasi di mana itu berguna seperti menguji atau menyimpan status permainan atau serupa. Dalam situasi tersebut, teknik pra-Jawa 1.7 yang ditunjukkan di bawah ini dapat digunakan.

Sebelum Java 1.7 , cara standar untuk melakukan ini adalah sebagai berikut:

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

Lihat JavaDoc yang relevan . Dalam praktiknya, kelas java.util.Random sering lebih disukai daripada java.lang.Math.random () .

Secara khusus, tidak perlu menemukan kembali roda pembangkitan bilangan bulat acak ketika ada API langsung dalam pustaka standar untuk menyelesaikan tugas.

Greg Case
sumber
43
Untuk panggilan yang maxnilainya Integer.MAX_VALUEdimungkinkan melimpah, menghasilkan a java.lang.IllegalArgumentException. Anda dapat mencoba dengan: randInt(0, Integer.MAX_VALUE). Juga, jika nextInt((max-min) + 1)mengembalikan nilai paling tinggi (sangat jarang, saya berasumsi) tidak akan meluap lagi (seandainya min dan maks adalah nilai yang cukup tinggi)? Bagaimana cara menghadapi situasi seperti ini?
Daniel
3
@MoisheLipsker Pasti nextLong tidak terikat sebagai nextInteger
mmm
13
@leventov ThreadLocalRandomditambahkan ke Java 2 1/2 tahun setelah pertanyaan ini pertama kali ditanyakan. Saya selalu berpendapat bahwa manajemen instance Acak berada di luar ruang lingkup pertanyaan.
Greg Case
6
Di Android Random rand = Random baru ();
Webserveis
5
@ Webserveis Ini dibahas dalam komentar dalam contoh. Versi singkat - Anda tidak boleh = Random baru () untuk setiap panggilan ke fungsi, atau hasil Anda tidak akan cukup acak untuk banyak kasus.
Greg Case
1422

Perhatikan bahwa pendekatan ini lebih bias dan kurang efisien daripada nextIntpendekatan, https://stackoverflow.com/a/738651/360211

Satu pola standar untuk mencapai ini adalah:

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

The Java Math fungsi library Math.random () menghasilkan nilai ganda dalam kisaran[0,1) . Perhatikan kisaran ini tidak termasuk 1.

Untuk mendapatkan rentang nilai tertentu terlebih dahulu, Anda perlu mengalikan dengan besarnya rentang nilai yang ingin Anda liput.

Math.random() * ( Max - Min )

Ini mengembalikan nilai dalam rentang [0,Max-Min) , di mana 'Max-Min' tidak termasuk.

Misalnya, jika Anda ingin [5,10), Anda harus mencakup lima nilai integer sehingga Anda gunakan

Math.random() * 5

Ini akan mengembalikan nilai dalam rentang [0,5) , di mana 5 tidak termasuk.

Sekarang Anda perlu menggeser rentang ini ke kisaran yang Anda targetkan. Anda melakukan ini dengan menambahkan nilai Min.

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

Anda sekarang akan mendapatkan nilai dalam rentang tersebut [Min,Max). Mengikuti contoh kita, itu berarti [5,10):

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

Tapi, ini masih belum termasuk Maxdan Anda mendapatkan nilai ganda. Untuk Maxmemasukkan nilai, Anda perlu menambahkan 1 ke rentang parameter Anda (Max - Min)dan kemudian memotong bagian desimal dengan melakukan casting ke int. Ini dicapai melalui:

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

Dan begitulah. Nilai integer acak dalam rentang [Min,Max], atau per contoh [5,10]:

5 + (int)(Math.random() * ((10 - 5) + 1))
TJ_Fischer
sumber
82
Dokumentasi Sun secara eksplisit mengatakan bahwa Anda sebaiknya menggunakan Random () jika Anda memerlukan int daripada Math.random () yang menghasilkan double.
Lilian A. Moraru
6
Ini sebenarnya bias dibandingkan dengan metode nextInt stackoverflow.com/a/738651/360211
weston
4
"Bias" dalam kasus ini berarti bahwa setelah 2 ^ 53 eksekusi, beberapa angka akan memiliki satu kejadian ekstra, rata-rata.
Cephalopod
378

Menggunakan:

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

Bilangan bulat xsekarang adalah angka acak yang memiliki kemungkinan hasil 5-10.

Martijn Pieters
sumber
159

Menggunakan:

minimum + rn.nextInt(maxValue - minvalue + 1)
krosenvold
sumber
137

Dengan mereka memperkenalkan metode ints(int randomNumberOrigin, int randomNumberBound)di Randomkelas.

Misalnya jika Anda ingin menghasilkan lima bilangan bulat acak (atau satu) di kisaran [0, 10], lakukan saja:

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

Parameter pertama menunjukkan hanya ukuran yang IntStreamdihasilkan (yang merupakan metode kelebihan yang menghasilkan tidak terbatas IntStream).

Jika Anda perlu melakukan beberapa panggilan terpisah, Anda dapat membuat iterator primitif tak terbatas dari aliran:

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

Anda juga dapat melakukannya untuk doubledan longmenghargai. Saya harap ini membantu! :)

Alexis C.
sumber
1
Saya menyarankan agar Anda instantiate randomIterator hanya sekali. Lihat komentar Greg Case pada jawabannya sendiri.
Naxos84
jika Anda bisa, bisakah Anda menjelaskan apa pentingnya streamSize- parameter pertama dari metode ini diberikan streamSize !=0. Apa perbedaannya jika streamSize1/2 / n diberikan?
Erfan Ahmed
104

Anda dapat mengedit contoh kode kedua Anda ke:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;
Bill the Lizard
sumber
100

Cukup modifikasi kecil dari solusi pertama Anda sudah cukup.

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

Lihat lebih lanjut di sini untuk implementasi Random

hexabunny
sumber
Untuk minimum <= nilai <maksimum, saya melakukan hal yang sama dengan Math: randomNum = minimum + (int) (Math.random () * (maksimum-minimum)); tapi castingnya tidak terlalu bagus untuk dilihat;)
AxelH
Paling lambat 7 tahun jawaban rangkap.
Maarten Bodewes
70

ThreadLocalRandomsetara dengan kelas java.util.Randomuntuk lingkungan multithreaded. Menghasilkan nomor acak dilakukan secara lokal di masing-masing utas. Jadi kami memiliki kinerja yang lebih baik dengan mengurangi konflik.

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

x, y- interval misalnya (1,10)

andrew
sumber
66

The Math.Randomkelas dalam Java adalah 0 berbasis. Jadi, jika Anda menulis sesuatu seperti ini:

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

xakan berada di antara 0-9inklusif.

Jadi, mengingat 25item array berikut , kode untuk menghasilkan angka acak antara 0(basis array) dan array.lengthakan menjadi:

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

index = rand.nextInt( i.length );

Karena i.lengthakan kembali 25, nextInt( i.length )akan mengembalikan angka di antara kisaran 0-24. Pilihan lainnya adalah Math.Randomyang bekerja dengan cara yang sama.

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

Untuk pemahaman yang lebih baik, lihat posting forum Interval Acak (archive.org) .

Matt R
sumber
+1 untuk tautan screenshot arsip wayBackMachine & jawaban Anda masih merupakan referensi yang berguna untuk mendapatkan int "acak" dengan rentang.
Tapper7
Ini membuat saya heran mengapa Anda membuat indeks menjadi 0.
AjahnCharles
@CodeConfident indexVariabel tidak akan memengaruhi hasil angka acak. Anda dapat memilih untuk menginisialisasi dengan cara apa pun yang Anda inginkan tanpa harus khawatir mengubah hasilnya. Semoga ini membantu.
Matt R
Tepat ... itu benar-benar tidak digunakan. Saya akan menginisialisasi langsung ke rand:int index = rand.nextInt(i.Length);
AjahnCharles
Atau tidak sama sekali. int index; \n index = rand...jika seseorang menyukai deklarasi dan penugasan pada baris yang berbeda. Beberapa standar pengkodean lebih ketat (dan tanpa tujuan yang jelas) daripada yang lain.
Mark Storer
49

Maafkan saya karena teliti, tetapi solusi yang disarankan oleh mayoritas, yaitu min + rng.nextInt(max - min + 1)), tampaknya berbahaya karena fakta bahwa:

  • rng.nextInt(n) tidak dapat dicapai Integer.MAX_VALUE .
  • (max - min)dapat menyebabkan kelebihan ketika minnegatif.

Solusi yang sangat mudah akan memberikan hasil yang benar untuk semua yang ada min <= maxdalam [ Integer.MIN_VALUE, Integer.MAX_VALUE]. Pertimbangkan implementasi naif berikut:

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

Meskipun tidak efisien, perhatikan bahwa probabilitas keberhasilan dalam whileloop akan selalu 50% atau lebih tinggi.

Joel Sjöstrand
sumber
Mengapa tidak melempar IllegalArgumentException ketika perbedaan = Integer.MAX_VALUE? Maka Anda tidak perlu loop sementara.
Anggota Parlemen Korstanje
3
@mpkorstanje Implementasi ini dirancang untuk bekerja dengan nilai min <= max, bahkan ketika perbedaannya sama atau bahkan lebih besar dari MAX_VALUE. Menjalankan loop sampai sukses adalah pola umum dalam kasus ini, untuk menjamin distribusi seragam (jika sumber dasar keacakan adalah seragam). Random.nextInt (int) melakukannya secara internal ketika argumennya bukan kekuatan 2.
Christian Semrau
44

Itu bisa dilakukan dengan hanya melakukan pernyataan:

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

Di bawah ini adalah kode sumbernya

Randomizer.java

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

Itu bersih dan sederhana.

Abel Callejo
sumber
5
Ini bisa jadi merupakan edit dari contoh lain, sekarang itu hanya salinan untuk reputasi. Menunjukkan "jawaban dengan suara terbanyak" juga tidak terlalu langsung, itu bisa berubah.
Maarten Bodewes
1
Itu benar @ MaartenBodewes. Ketika saya menulis jawaban ini, jawaban dengan suara terbanyak di atas masih ditulis sebagai solusi seperti algoritma. Sekarang, solusi di atas telah banyak berubah dan sekarang jawaban ini tampak seperti copy-cat.
Abel Callejo
Saya benar-benar tidak mengerti mengapa bit kode fundamental seperti itu bukan bagian dari perpustakaan standar Java. Mengapa saya harus menerapkan ini?
Leevi L
31

Mari kita ambil contoh.

Misalkan saya ingin menghasilkan angka antara 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);

Mari kita pahami ini ...

Inisialisasi maks dengan nilai tertinggi dan min dengan nilai terendah.

Sekarang, kita perlu menentukan berapa banyak nilai yang mungkin dapat diperoleh. Untuk contoh ini, itu akan menjadi:

5, 6, 7, 8, 9, 10

Jadi, hitungan ini akan menjadi maksimum - min + 1.

yaitu 10 - 5 + 1 = 6

Angka acak akan menghasilkan angka antara 0-5 .

yaitu 0, 1, 2, 3, 4, 5

Menambahkan nilai min ke angka acak akan menghasilkan:

5, 6, 7, 8, 9, 10

Karenanya kami memperoleh kisaran yang diinginkan.

Sunil Chawla
sumber
29
 rand.nextInt((max+1) - min) + min;
Michael Myers
sumber
26

Hasilkan angka acak untuk perbedaan min dan maks dengan menggunakan metode nextint (n) dan kemudian tambahkan angka min ke hasilnya:

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

Saya menggunakan ini:

 /**
   * @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;
 }

Anda bisa melemparkannya ke Integer jika mau.

Simon
sumber
Fungsi ini menghasilkan angka yang sama berulang-ulang. Dalam kasus saya itu adalah: 2147483647
sokras
Gagal: Anda memiliki fungsi yang memerlukan ganda dan kemudian melakukan +1? Ini tentu saja bertentangan dengan prinsip paling tidak mengejutkan. Apa yang terjadi jika Anda menggunakan min = 0,1 dan maks = 0,2?
Maarten Bodewes
@sokras memanggil metode new Random(periksa JavaDoc): "Membuat generator nomor acak baru. Konstruktor ini mengatur seed dari generator nomor acak ke nilai yang sangat mungkin berbeda dari permintaan lain dari konstruktor ini." Sangat mungkin hanya melibatkan menggunakan waktu saat ini sebagai benih. Jika waktu itu menggunakan milidetik maka komputer saat ini cukup cepat untuk menghasilkan angka yang sama. Namun selain itu 2147483647 adalah Integer.MAX_VALUE; output jelas tergantung pada input, yang belum Anda tentukan.
Maarten Bodewes
Akhirnya menemukan satu yang benar-benar berfungsi
Jency
23

Pada Java 7, Anda tidak boleh lagi menggunakan Random. Untuk sebagian besar kegunaan, generator nomor acak pilihan sekarang ThreadLocalRandom.

Untuk garpu bergabung dengan kolam dan aliran paralel, gunakan SplittableRandom.

Joshua Bloch. Jawa yang efektif. Edisi ketiga.

Mulai dari Jawa 8

Untuk cabang gabungan garpu dan aliran paralel, gunakan SplittableRandomyang biasanya lebih cepat, memiliki kemandirian statistik yang lebih baik dan sifat keseragaman dibandingkan dengan Random.

Untuk menghasilkan acak intdalam kisaran[0, 1_000]:

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

Untuk menghasilkan int[100]array nilai acak dalam rentang[0, 1_000]:

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

Untuk mengembalikan Stream nilai acak:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
Oleksandr Pyrohov
sumber
Apakah ada alasan mengapa contohnya termasuk a .parallel()? Sepertinya saya seperti menghasilkan 100 angka acak akan terlalu sepele untuk menjamin paralelisme.
Johnbot
@ Johnbot Terima kasih atas komentarnya, Anda benar. Tapi, alasan utama adalah untuk menunjukkan API (tentu saja, jalur pintar adalah untuk mengukur kinerja sebelum menggunakan parallelpemrosesan). By the way, untuk array 1_000_000elemen, parallelversi itu 2 kali lebih cepat pada mesin saya dibandingkan dengan berurutan.
Oleksandr Pyrohov
21

Cukup gunakan kelas Acak :

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);
Prof Mo
sumber
8
Saya tidak melihat sesuatu yang baru di sini yang belum diposting di posting sebelumnya yang tak terhitung jumlahnya.
Maarten Bodewes
20

Metode ini mungkin nyaman digunakan:

Metode ini akan mengembalikan angka acak antara nilai minimum dan maksimum yang disediakan:

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

dan metode ini akan mengembalikan angka acak dari nilai min dan max yang disediakan (sehingga angka yang dihasilkan juga bisa berupa angka min atau max):

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

    return randomNumber;
}
Luke Taylor
sumber
// Since the random number is between the min and max values, simply add 1. Mengapa? Tidak dihitung? Biasanya kisarannya adalah [min, maks) di mana min disertakan dan maks dikecualikan. Jawaban salah, ditolak.
Maarten Bodewes
@MaartenBodewes +1 ditambahkan karena getRandomNumberBetween menghasilkan nomor acak eksklusif dari titik akhir yang disediakan.
Luke Taylor
1
Jumlahnya min + 1akan dua kali lipat dari angka yang akan dihasilkan getRandomNumberBetween!
Lii
19

Dalam hal menggulirkan dadu itu akan menjadi angka acak antara 1 hingga 6 (bukan 0 hingga 6), jadi:

face = 1 + randomNumbers.nextInt(6);
sam
sumber
19
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();

Atau lihat RandomUtils dari Apache Commons .

pengguna2427
sumber
Itu berguna, tetapi waspadalah terhadap cacat kecil: tanda tangan metode seperti: nextDouble (double startInclusive, double endInclusive), tetapi jika Anda melihat ke dalam metode, endInclusive sebenarnya harus endExclusive.
zakmck
Double.valueOf(Math.random()*(maximum-minimun)).intValue()adalah cara yang sangat membingungkan (dan tidak efisien) untuk mengatakan (int)(Math.random()*(maximum-minimun))...
Holger
Ketidakcocokan ejaan untuk minimum pengembalian minimum + Double.valueOf (Math.random () * (maksimum - minimum)). IntValue ();
Hrishikesh Mishra
18

Berikut adalah kelas yang membantu untuk menghasilkan acak intsdalam kisaran dengan kombinasi batas inklusif / eksklusif:

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
sumber
18

Untuk menghasilkan angka acak "di antara dua angka", gunakan kode berikut:

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

Ini memberi Anda angka acak di antara 1 (inklusif) dan 11 (eksklusif), jadi inisialisasi nilai upperBound dengan menambahkan 1. Misalnya, jika Anda ingin menghasilkan angka acak antara 1 hingga 10 maka inisialisasi angka upperBound dengan 11 alih-alih 10.

Lawakush Kurmi
sumber
18

Anda dapat mencapainya secara ringkas di 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);
Mulalo Madida
sumber
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_
sumber
16

Opsi lain hanya menggunakan 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
sumber
16

Saya menemukan contoh ini Menghasilkan angka acak :


Contoh ini menghasilkan bilangan bulat acak dalam rentang tertentu.

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

Contoh menjalankan kelas ini:

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.
Rumah sakit
sumber
14

Lebih baik menggunakan SecureRandom daripada hanya Acak.

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
sumber
1
Ini tidak begitu baik, karena jika dijalankan dalam mili yang sama maka Anda akan mendapatkan nomor yang sama, Anda perlu meletakkan inisialisasi rand dan setSeet di luar metode.
maraca
Anda perlu seed, ya, tetapi menggunakan SecureRandom.
grep
Maaf, tetapi orang yang menolak permintaan perubahan tidak memiliki petunjuk tentang pemrograman Java. Ini adalah saran yang bagus, tetapi karena itu salah karena jika dijalankan dalam mili yang sama, ia akan memberikan nomor yang sama, bukan acak.
maraca
Solusi yang tepat tidak dapat ditemukan di mana pun, tidak banyak orang yang tahu blok penginisialisasi statis ... itulah yang harus Anda gunakan untuk mengatur seed: 1: private static int SecureRandom rand = new SecureRandom();2: static {3: rand.setSeed(...);4:}
maraca
5
Sama sekali tidak perlu untuk menanam SecureRandom, itu akan diunggulkan oleh sistem. Memanggil secara langsung setSeedsangat berbahaya, mungkin mengganti benih (benar-benar acak) dengan tanggal. Dan itu tentu saja tidak akan menghasilkan SecureRandom, karena siapa pun dapat menebak waktu dan mencoba dan menyemai SecureRandomcontoh mereka sendiri dengan informasi itu.
Maarten Bodewes
13

Berikut adalah contoh sederhana yang menunjukkan cara menghasilkan angka acak dari [min, max]rentang tertutup , sementaramin <= max is true

Anda dapat menggunakannya kembali sebagai bidang dalam kelas lubang, juga memiliki semua Random.classmetode di satu tempat

Contoh hasil:

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

Sumber:

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;
    }
}
Yakiv Mospan
sumber
13
rand.nextInt((max+1) - min) + min;

Ini bekerja dengan baik.

Ganesh
sumber