如何在特定范围内生成随机int值?

以下方法存在与整数溢出相关的错误:

randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.
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 17引入了RandomGenerator接口,它提供了一个int nextInt(int origin,int bound)方法来获取范围内的随机整数:

// Returns a random int between minimum (inclusive) & maximum (exclusive)
int randomInt = RandomGenerator.getDefault().nextInt(minimum, maximum);

除了用于Java17中添加的新的随机生成算法之外,该接口还添加到现有的随机生成类(random、SecureRandom、SplitableRandom和ThreadLocalRandom)中。因此,从Java 17开始,这些类具有以下有界nextInt方法:

new Random().nextInt(minimum, maximum);
new SecureRandom().nextInt(minimum, maximum);
new SplittableRandom().nextInt(minimum, maximum);
new ThreadLocalRandom().nextInt(minimum, maximum);

从Java17开始,这种方法是Random和SecureRandom的新方法。在Java17之前,ThreadLocalRandom和SplitableRandom已经有了这个方法,尽管它不是由共享接口指定的。

其他回答

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

我将简单地说明问题提供的解决方案有什么问题,以及错误的原因。

解决方案1:

randomNum = minimum + (int)(Math.random()*maximum); 

问题:randomNum分配的值大于最大值。

解释:假设我们的最小值是5,而你的最大值是10。Math.random()中任何大于0.6的值都将使表达式的计算结果为6或更大,加上5将使其大于10(最大值)。问题是你将随机数乘以最大值(这会产生一个几乎和最大值一样大的数字),然后再加上最小值。除非最小值是1,否则它是不正确的。如其他答案所述,您必须切换到

randomNum = minimum + (int)(Math.random()*(maximum-minimum+1))

+1是因为Math.random()永远不会返回1.0。

解决方案2:

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

这里的问题是,如果第一项小于0,“%”可能会返回负数。由于rn.nextInt()以约50%的概率返回负值,因此也不会得到预期的结果。

然而,这几乎是完美的。您只需进一步查看Javadoc,nextInt(int n)。使用该方法

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

也将返回所需的结果。

使用Apache Lang3 Commons

Integer.parseInt(RandomStringUtils.randomNumeric(6, 6));

最小值100000到最大值999999

在尝试1中进行以下更改应该可以完成工作-

randomNum = minimum + (int)(Math.random() * (maximum - minimum) );

检查此项以获取工作代码。

使用nexttint(n)方法为最小值和最大值的差值生成一个随机数,然后将最小值添加到结果中:

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