如何在特定范围内生成随机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`.
从Java7开始,您应该不再使用Random。对于大多数用途选择的随机数生成器现在ThreadLocalRandom。用于fork连接池和并行流,使用SplitableRandom。
乔舒亚·布洛赫。有效的Java。第三版。
从Java 8开始
对于fork-join池和并行流,请使用SplittableRandom,它通常更快,与Random相比具有更好的统计独立性和一致性财产。
要生成[0,1_000]范围内的随机整数:
int n = new SplittableRandom().nextInt(0, 1_001);
要生成[0,1_000]范围内的随机整数[100]数组,请执行以下操作:
int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray();
要返回随机值流:
IntStream stream = new SplittableRandom().ints(100, 0, 1_001);
这将生成范围(最小值-最大值)不重复的随机数列表。
generateRandomListNoDuplicate(1000, 8000, 500);
添加此方法。
private void generateRandomListNoDuplicate(int min, int max, int totalNoRequired) {
Random rng = new Random();
Set<Integer> generatedList = new LinkedHashSet<>();
while (generatedList.size() < totalNoRequired) {
Integer radnomInt = rng.nextInt(max - min + 1) + min;
generatedList.add(radnomInt);
}
}
希望这对你有所帮助。
我将简单地说明问题提供的解决方案有什么问题,以及错误的原因。
解决方案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;
也将返回所需的结果。