如何在Java中的特定範圍內生成隨機整數?


Answers

請注意,這種方法比nextInt方法更有偏見,效率更低, https://stackoverflow.com/a/738651/360211 : nextInt

完成這個的一個標準模式是:

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

Java Math庫函數Math.random()在[0,1)範圍內生成一個double值。 注意這個範圍不包括1。

為了首先獲得特定範圍的值,您需要乘以您想要覆蓋的值範圍的大小。

Math.random() * ( Max - Min )

這將返回範圍[0,Max-Min)中的一個值,其中不包括“Max-Min”。

例如,如果你想[5,10] ,你需要覆蓋五個整數值,所以你使用

Math.random() * 5

這將返回範圍[0,5)中的一個值,其中不包括5。

現在您需要將此範圍調整到您定位的範圍。 您可以通過添加最小值來完成此操作。

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

您現在將獲得[Min,Max)範圍內的值。 按照我們的例子,這意味著[5,10)

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

但是,這仍然不包括Max並且您獲得了雙倍的價值。 為了獲得Max ,你需要在你的範圍參數(Max - Min)加1,然後通過強制轉換為int來截斷小數部分。 這通過以下方式完成:

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

在那裡你有它。 範圍[Min,Max]或每個示例[5,10]中的隨機整數值:

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

如何在特定範圍內生成隨機int值?

我嘗試了以下,但那些不起作用:

嘗試1:

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

嘗試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`.



您可以在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);



import java.util.Random; 

public class RandomUtil {
    // Declare as class variable so that it is not re-seeded every call
    private static Random random = new Random();

    /**
     * Returns a psuedo-random number between min and max (both inclusive)
     * @param min Minimim value
     * @param max Maximim value. Must be greater than min.
     * @return Integer between min and max (both inclusive)
     * @see java.util.Random#nextInt(int)
     */
    public static int nextInt(int min, int max) {
        // nextInt is normally exclusive of the top value,
        // so add 1 to make it inclusive
        return random.nextInt((max - min) + 1) + min;
    }
}



你可以編輯你的第二個代碼示例來:

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



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

或者看看Apache Commons的 RandomUtils。




只需使用Random類:

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



請原諒我講究,但大多數人提出的解決方案,即min + rng.nextInt(max - min + 1)) ,似乎是危險的,因為這樣一個事實:

  • rng.nextInt(n)無法達到Integer.MAX_VALUE
  • (max - min)可能會在min為負時導致溢出。

萬無一失的解決方案將在[ Integer.MIN_VALUEInteger.MAX_VALUE ]內返回任何min <= max正確結果。 考慮以下簡單的實現:

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

雖然效率不高,但請注意, while循環中成功的概率將始終為50%或更高。




這種方法可能方便使用:

該方法將在提供的最小值和最大值之間返回一個隨機數:

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

此方法將從提供的最小值和最大值中返回一個隨機數(因此生成的數字也可以是最小值或最大值):

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

    return randomNumber;
}



用於多線程環境的ThreadLocalRandom等同於java.util.Random類。 生成一個隨機數是在每個線程中進行的。 所以我們通過減少衝突來獲得更好的表現。

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

x,y - 間隔例如(1,10)




使用:

minimum + rn.nextInt(maxValue - minvalue + 1)



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

這工作正常。




使用nextint(n)方法為最小值和最大值的差值生成一個隨機數,然後將最小值添加到結果中:

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



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



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



最好使用SecureRandom而不是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;
}