Làm cách nào để tạo các số nguyên ngẫu nhiên trong một phạm vi cụ thể trong Java?


3505

Làm cách nào để tạo một intgiá trị ngẫu nhiên trong một phạm vi cụ thể?

Tôi đã thử những cách sau, nhưng những thứ đó không hoạt động:

Nỗ lực 1:

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

Cố gắng 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`.

Khi bạn cần nhiều số ngẫu nhiên, tôi không đề xuất lớp Ngẫu nhiên trong API. Nó chỉ có một khoảng thời gian quá nhỏ. Thay vào đó hãy thử twister Mersenne . Có một triển khai Java .
raupach

1
Trước khi bạn đăng câu trả lời mới, hãy xem xét đã có hơn 65 câu trả lời cho câu hỏi này. Xin vui lòng, đảm bảo rằng câu trả lời của bạn đóng góp thông tin không nằm trong số các câu trả lời hiện có.
janniks

Câu trả lời:


3801

Trong Java 1.7 trở lên , cách tiêu chuẩn để làm điều này như sau:

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

Xem JavaDoc có liên quan . Cách tiếp cận này có ưu điểm là không cần phải khởi tạo một cách rõ ràng một cá thể java.util.Random , đây có thể là một nguồn gây nhầm lẫn và lỗi nếu được sử dụng không phù hợp.

Tuy nhiên, ngược lại, không có cách nào để thiết lập hạt giống một cách rõ ràng để có thể khó tái tạo kết quả trong các tình huống có ích như kiểm tra hoặc lưu trạng thái trò chơi hoặc tương tự. Trong các tình huống đó, kỹ thuật tiền Java 1.7 được hiển thị bên dưới có thể được sử dụng.

Trước Java 1.7 , cách tiêu chuẩn để làm điều này như sau:

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

Xem JavaDoc có liên quan . Trong thực tế, lớp java.util.Random thường được ưa thích hơn java.lang.Math.random () .

Đặc biệt, không cần phải phát minh lại bánh xe tạo số nguyên ngẫu nhiên khi có API đơn giản trong thư viện chuẩn để hoàn thành nhiệm vụ.


43
Đối với các cuộc gọi trong đó maxgiá trị là Integer.MAX_VALUEcó thể tràn, dẫn đến a java.lang.IllegalArgumentException. Bạn có thể thử với : randInt(0, Integer.MAX_VALUE). Ngoài ra, nếu nextInt((max-min) + 1)trả về giá trị cao nhất (khá hiếm, tôi giả sử) sẽ không bị tràn nữa (giả sử tối thiểu và tối đa là giá trị đủ cao)? Làm thế nào để đối phó với loại tình huống này?
Daniel

3
@MoisheLipsker Phải là nextLong không bị ràng buộc như nextInteger
mmm

13
@leventov ThreadLocalRandomđã được thêm vào Java 2 năm rưỡi sau khi câu hỏi này được hỏi lần đầu tiên. Tôi luôn có quan điểm chắc chắn rằng việc quản lý đối tượng Ngẫu nhiên nằm ngoài phạm vi của câu hỏi.
Trường hợp Greg

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

5
@Webserveis Điều này được đề cập trong các ý kiến ​​trong ví dụ. Phiên bản ngắn - bạn không nên = new Random () cho mỗi cuộc gọi đến chức năng, hoặc kết quả của bạn sẽ không đủ ngẫu nhiên trong nhiều trường hợp.
Trường hợp Greg

1422

Lưu ý rằng phương pháp này thiên vị hơn và kém hiệu quả hơn nextIntphương pháp, https://stackoverflow.com/a/738651/360211

Một mô hình chuẩn để thực hiện điều này là:

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

Hàm thư viện Java Math Math.random () tạo ra một giá trị kép trong phạm vi[0,1) . Lưu ý phạm vi này không bao gồm 1.

Để có được một phạm vi giá trị cụ thể trước tiên, bạn cần nhân với độ lớn của phạm vi giá trị bạn muốn bảo hiểm.

Math.random() * ( Max - Min )

Điều này trả về một giá trị trong phạm vi [0,Max-Min) , trong đó 'Max-Min' không được bao gồm.

Ví dụ: nếu bạn muốn [5,10), bạn cần bao gồm năm giá trị số nguyên để bạn sử dụng

Math.random() * 5

Điều này sẽ trả về một giá trị trong phạm vi [0,5) , trong đó 5 không được bao gồm.

Bây giờ bạn cần chuyển phạm vi này lên phạm vi mà bạn đang nhắm mục tiêu. Bạn làm điều này bằng cách thêm giá trị Min.

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

Bây giờ bạn sẽ nhận được một giá trị trong phạm vi [Min,Max). Theo ví dụ của chúng tôi, điều đó có nghĩa là [5,10):

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

Nhưng, điều này vẫn không bao gồm Maxvà bạn đang nhận được một giá trị gấp đôi. Để có được Maxgiá trị được bao gồm, bạn cần thêm 1 vào tham số phạm vi của mình (Max - Min)và sau đó cắt phần thập phân bằng cách chuyển sang int. Điều này được thực hiện thông qua:

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

Và bạn có nó rồi đấy! Một giá trị số nguyên ngẫu nhiên trong phạm vi [Min,Max]hoặc theo ví dụ [5,10]:

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

82
Tài liệu của Sun nói rõ ràng rằng bạn nên sử dụng Random () tốt hơn nếu bạn cần một int thay vì Math.random () tạo ra gấp đôi.
Lilian A. Moraru

6
Điều này thực sự sai lệch so với các phương thức nextInt stackoverflow.com/a/738651/360211
weston

4
"Xu hướng" trong trường hợp này có nghĩa là sau 2 ^ 53 lần thực hiện, trung bình một số con số sẽ có thêm một lần xuất hiện.
Cephalepad

378

Sử dụng:

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

Số nguyên xbây giờ là số ngẫu nhiên có kết quả có thể là 5-10.



137

Với họ đã giới thiệu phương pháp ints(int randomNumberOrigin, int randomNumberBound)trong Randomlớp.

Ví dụ: nếu bạn muốn tạo năm số nguyên ngẫu nhiên (hoặc một số nguyên) trong phạm vi [0, 10], chỉ cần làm:

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

Tham số đầu tiên chỉ ra kích thước của phương thức IntStreamđược tạo (là phương thức quá tải của phương thức tạo ra không giới hạn IntStream).

Nếu bạn cần thực hiện nhiều cuộc gọi riêng biệt, bạn có thể tạo một trình vòng lặp nguyên thủy vô hạn từ luồng:

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

Bạn cũng có thể làm điều đó cho doublelongcác giá trị. Tôi hy vọng nó sẽ giúp! :)


1
Tôi sẽ đề nghị bạn khởi tạo RandomIterator chỉ một lần. Xem Greg Case bình luận về câu trả lời của riêng mình.
Naxos84

nếu bạn có thể, bạn có thể giải thích tầm quan trọng của streamSize- thông số đầu tiên của phương pháp này được đưa ra streamSize !=0. Sự khác biệt nếu streamSize1/2 / n được đưa ra là gì?
Erfan Ahmed

104

Bạn có thể chỉnh sửa ví dụ mã thứ hai của mình thành:

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

100

Chỉ cần một sửa đổi nhỏ của giải pháp đầu tiên của bạn là đủ.

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

Xem thêm ở đây để thực hiện Random


Đối với tối thiểu <= value <tối đa, tôi đã làm tương tự với Math: RandomNum = tối thiểu + (int) (Math.random () * (tối đa-tối thiểu)); nhưng buổi casting không thực sự tốt để xem;)
AxelH

Ít nhất 7 năm trễ trả lời trùng lặp.
Maarten Bodewes

70

ThreadLocalRandomtương đương với lớp học java.util.Randomcho môi trường đa luồng. Tạo một số ngẫu nhiên được thực hiện cục bộ trong mỗi luồng. Vì vậy, chúng tôi có một hiệu suất tốt hơn bằng cách giảm các xung đột.

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

x, y- khoảng thời gian, ví dụ (1,10)


66

Các Math.Randomlớp trong Java là 0-based. Vì vậy, nếu bạn viết một cái gì đó như thế này:

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

xsẽ được 0-9bao gồm giữa .

Vì vậy, với mảng các 25mục sau đây , mã để tạo một số ngẫu nhiên nằm giữa 0(cơ sở của mảng) và array.lengthsẽ là:

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

index = rand.nextInt( i.length );

i.lengthsẽ trả về 25, nextInt( i.length )sẽ trả về một số giữa phạm vi 0-24. Tùy chọn khác là đi với Math.Randomcái nào hoạt động theo cùng một cách.

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

Để hiểu rõ hơn, hãy xem bài đăng trên diễn đàn Khoảng thời gian ngẫu nhiên (archive.org) .


+1 cho liên kết ảnh chụp màn hình lưu trữ wayBackMachine & câu trả lời của bạn vẫn là tài liệu tham khảo hữu ích để có được số liệu "ngẫu nhiên" w / trong một phạm vi.
Tapper7

Nó gây khó khăn cho tôi tại sao bạn khởi tạo chỉ số về 0.
AjahnCharles

@CodeConfident indexBiến sẽ không ảnh hưởng đến kết quả của số ngẫu nhiên. Bạn có thể chọn khởi tạo nó theo bất kỳ cách nào bạn muốn mà không phải lo lắng về việc thay đổi kết quả. Hi vọng điêu nay co ich.
Matt R

Chính xác ... nó hoàn toàn không được sử dụng. Tôi sẽ khởi tạo nó trực tiếp đến rand:int index = rand.nextInt(i.Length);
AjahnCharles

Hoặc không phải ở tất cả. int index; \n index = rand...nếu một người thích khai báo và bài tập trên các dòng khác nhau. Một số tiêu chuẩn mã hóa nghiêm ngặt hơn (và không có mục đích rõ ràng) so với các tiêu chuẩn khác.
Mark Storer

49

Hãy tha thứ cho tôi vì khó tính, nhưng giải pháp được đa số đề xuất, có nghĩa là min + rng.nextInt(max - min + 1)), có vẻ nguy hiểm do thực tế là:

  • rng.nextInt(n)không thể đạt được Integer.MAX_VALUE.
  • (max - min)có thể gây tràn khi minâm.

Một giải pháp hoàn hảo sẽ trả về kết quả chính xác cho bất kỳ min <= maxtrong [ Integer.MIN_VALUE, Integer.MAX_VALUE]. Hãy xem xét việc thực hiện ngây thơ sau đây:

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

Mặc dù không hiệu quả, lưu ý rằng xác suất thành công trong whilevòng lặp sẽ luôn là 50% hoặc cao hơn.


Tại sao không ném IllegalArgumentException khi chênh lệch = Integer.MAX_VALUE? Sau đó, bạn không cần vòng lặp while.
MP Korstanje

3
@mpkorstanje Việc triển khai này được thiết kế để hoạt động với mọi giá trị tối thiểu <= max, ngay cả khi chênh lệch của chúng bằng hoặc thậm chí lớn hơn MAX_VALUE. Chạy một vòng lặp cho đến khi thành công là một mô hình phổ biến trong trường hợp này, để đảm bảo phân phối đồng đều (nếu nguồn ngẫu nhiên cơ bản là đồng nhất). Random.nextInt (int) thực hiện nội bộ khi đối số không phải là sức mạnh của 2.
Christian Semrau

44

Nó có thể được thực hiện bằng cách đơn giản là thực hiện tuyên bố:

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

Dưới đây là mã nguồn của nó

Randomizer.java

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

Nó chỉ là sạch sẽ và đơn giản.


5
Đây có thể là một bản chỉnh sửa của ví dụ khác, bây giờ nó chỉ là một bản sao trắng trợn cho danh tiếng. Chỉ ra "câu trả lời có nhiều phiếu nhất" cũng không trực tiếp lắm, nó có thể thay đổi.
Maarten Bodewes

1
Đúng vậy @MaartenBodewes. Khi tôi viết câu trả lời này, câu trả lời có nhiều phiếu nhất ở trên vẫn được viết dưới dạng một giải pháp giống như thuật toán. Bây giờ, giải pháp ở trên đã thay đổi rất nhiều và bây giờ câu trả lời này trông giống như một con mèo sao chép.
Abel Callejo

Tôi thực sự không hiểu tại sao các đoạn mã cơ bản như vậy không phải là một phần của các thư viện chuẩn Java. Tại sao tôi phải thực hiện điều này?
Leevi L


31

Chúng ta hãy lấy một ví dụ.

Giả sử tôi muốn tạo một số trong khoảng 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);

Hãy để chúng tôi hiểu điều này ...

Khởi tạo max với giá trị cao nhất và min với giá trị thấp nhất.

Bây giờ, chúng ta cần xác định có bao nhiêu giá trị có thể có được. Trong ví dụ này, nó sẽ là:

5, 6, 7, 8, 9, 10

Vì vậy, số lượng này sẽ là tối đa - tối thiểu + 1.

tức là 10 - 5 + 1 = 6

Số ngẫu nhiên sẽ tạo ra một số trong khoảng 0-5 .

tức là 0, 1, 2, 3, 4, 5

Thêm giá trị tối thiểu vào số ngẫu nhiên sẽ tạo ra:

5, 6, 7, 8, 9, 10

Do đó chúng tôi có được phạm vi mong muốn.



26

Tạo một số ngẫu nhiên cho sự khác biệt của min và max bằng cách sử dụng phương thức nextint (n) và sau đó thêm số min vào kết quả:

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

26

Tôi sử dụng cái này:

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

Bạn có thể sử dụng nó cho một Integer nếu bạn muốn.


Hàm này tạo ra cùng một số nhiều lần. Trong trường hợp của tôi, đó là: 2147483647
sokras

Thất bại: bạn có một hàm yêu cầu gấp đôi và sau đó thực hiện + 1? Điều này chắc chắn đi ngược lại nguyên tắc ít bất ngờ nhất. Điều gì xảy ra nếu bạn sử dụng min = 0,1 và max = 0,2?
Maarten Bodewes

@sokras phương thức gọi new Random(kiểm tra JavaDoc): "Tạo trình tạo số ngẫu nhiên mới. Hàm tạo này đặt hạt giống của trình tạo số ngẫu nhiên thành một giá trị rất có thể khác với bất kỳ lệnh gọi nào khác của hàm tạo này." Rất có thể chỉ liên quan đến việc sử dụng thời gian hiện tại làm hạt giống. Nếu thời gian đó sử dụng mili giây thì các máy tính hiện tại đủ nhanh để tạo ra cùng một số. Nhưng bên cạnh đó 2147483647 là Integer.MAX_VALUE; đầu ra rõ ràng phụ thuộc vào đầu vào mà bạn chưa chỉ định.
Maarten Bodewes

Cuối cùng cũng tìm thấy một cái thực sự hoạt động
Jency

23

Kể từ Java 7, bạn không nên sử dụng nữa Random. Đối với hầu hết các mục đích sử dụng, trình tạo số ngẫu nhiên được lựa chọn hiện nay ThreadLocalRandom.

Đối với ngã ba tham gia nhóm và luồng song song, sử dụng SplittableRandom.

Joshua Bloch. Java hiệu quả. Ấn bản thứ ba.

Bắt đầu từ Java 8

Đối với nhóm tham gia ngã ba và các luồng song song, sử dụng SplittableRandomthường nhanh hơn, có tính độc lập thống nhất và tính đồng nhất tốt hơn so với Random.

Để tạo ngẫu nhiên inttrong phạm vi[0, 1_000]:

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

Để tạo một int[100]mảng giá trị ngẫu nhiên trong phạm vi[0, 1_000]:

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

Để trả về một luồng các giá trị ngẫu nhiên:

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

Có một lý do tại sao ví dụ bao gồm một .parallel()? Đối với tôi, dường như việc tạo ra 100 số ngẫu nhiên sẽ quá tầm thường để đảm bảo tính song song.
Johnbot

@Johnbot Cảm ơn bạn đã bình luận, bạn đã đúng. Nhưng, lý do chính là để hiển thị API (tất nhiên, đường dẫn thông minh là để đo hiệu suất trước khi sử dụng parallelxử lý). Nhân tiện, đối với mảng các 1_000_000yếu tố, parallelphiên bản nhanh hơn 2 lần trên máy của tôi so với tuần tự.
Oleksandr Pyrohov

21

Chỉ cần sử dụng lớp Ngẫu nhiên :

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

8
Tôi không thấy bất cứ điều gì mới ở đây đã không được đăng trong vô số bài viết trước đó.
Maarten Bodewes

20

Phương pháp này có thể thuận tiện để sử dụng:

Phương pháp này sẽ trả về một số ngẫu nhiên giữa giá trị tối thiểu và tối đa được cung cấp:

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

và phương thức này sẽ trả về một số ngẫu nhiên từ giá trị tối thiểu và tối đa được cung cấp (vì vậy số được tạo cũng có thể là số tối thiểu hoặc tối đa):

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. Tại sao? Không tính tối thiểu? Thông thường phạm vi là [min, max) trong đó min được bao gồm và max được loại trừ. Trả lời sai, bỏ phiếu xuống.
Maarten Bodewes

@MaartenBodewes +1 được thêm vào vì getRandomNumberB Among tạo một số ngẫu nhiên không bao gồm các điểm cuối được cung cấp.
Luke Taylor

1
Con số min + 1sẽ gấp đôi so với con số khác là kết quả của getRandomNumberBetween!
Lii

19

Trong trường hợp gieo xúc xắc, nó sẽ là số ngẫu nhiên trong khoảng từ 1 đến 6 (không phải từ 0 đến 6), vì vậy:

face = 1 + randomNumbers.nextInt(6);

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

Hoặc hãy xem RandomUtils từ Apache Commons .


Điều đó hữu ích, nhưng hãy cẩn thận một lỗ hổng nhỏ: chữ ký của phương thức giống như: nextDouble (double startInpol, double endIninating), nhưng nếu bạn nhìn vào bên trong các phương thức, endInpol thực sự sẽ là endExinating.
zakmck

Double.valueOf(Math.random()*(maximum-minimun)).intValue()là khá một cách obfuscated (và không hiệu quả) để nói (int)(Math.random()*(maximum-minimun))...
Holger

Lỗi chính tả cho tối thiểu trở lại tối thiểu + Double.valueOf (Math.random () * (tối đa - tối thiểu)). IntValue ();
Hrishikesh Mishra

18

Đây là một lớp hữu ích để tạo ngẫu nhiên intstrong một phạm vi với bất kỳ kết hợp giới hạn bao gồm / độc quyền nào:

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

Để tạo một số ngẫu nhiên "ở giữa hai số", hãy sử dụng mã sau:

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

Điều này cung cấp cho bạn một số ngẫu nhiên trong khoảng từ 1 (đã bao gồm) và 11 (độc quyền), vì vậy hãy khởi tạo giá trị UpperBound bằng cách thêm 1. Ví dụ: nếu bạn muốn tạo số ngẫu nhiên trong khoảng từ 1 đến 10 thì hãy khởi tạo số UpperBound bằng 11 thay vì 10.


18

Bạn có thể đạt được điều đó một cách chính xác trong 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);

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

Một tùy chọn khác là chỉ sử dụng 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

Tôi tìm thấy ví dụ này Tạo số ngẫu nhiên :


Ví dụ này tạo ra các số nguyên ngẫu nhiên trong một phạm vi cụ thể.

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

Một ví dụ chạy của lớp này:

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

Tốt hơn là sử dụng SecureRandom thay vì chỉ ngẫu nhiên.

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
Điều này là không tốt, bởi vì nếu nó được thực thi trong cùng một giây thì bạn sẽ nhận được cùng một số, bạn cần đặt khởi tạo rand và setSeet bên ngoài phương thức.
Marica

Bạn cần hạt giống, có, nhưng sử dụng SecureRandom.
grep

Tôi xin lỗi, nhưng người từ chối yêu cầu thay đổi không có đầu mối lập trình Java Đó là một gợi ý tốt, nhưng như vậy là sai bởi vì nếu được thực hiện trong cùng một giây thì nó sẽ cho cùng một số, không phải ngẫu nhiên.
Marica

Giải pháp chính xác không tìm thấy ở đâu, không nhiều người biết các khối khởi tạo tĩnh ... đó là những gì bạn nên sử dụng để đặt hạt giống: 1: private static int SecureRandom rand = new SecureRandom();2: static {3: rand.setSeed(...);4:}
maraca

5
Hoàn toàn không cần phải gieo hạt SecureRandom, nó sẽ được hệ thống gieo hạt. Gọi trực tiếp setSeedlà rất nguy hiểm, nó có thể thay thế hạt giống (thực sự ngẫu nhiên) bằng ngày. Và điều đó chắc chắn sẽ không dẫn đến một SecureRandom, vì bất kỳ ai cũng có thể đoán thời gian và thử và gieo hạt giống của họ SecureRandomvới thông tin đó.
Maarten Bodewes

13

Đây là một mẫu đơn giản cho thấy cách tạo số ngẫu nhiên từ [min, max]phạm vi đóng , trong khimin <= max is true

Bạn có thể sử dụng lại nó như là trường trong lớp lỗ, cũng có tất cả các Random.classphương thức ở một nơi

Ví dụ kết quả:

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

Nguồn:

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;

Điều này đang làm việc tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.