对于这题,网上一直找不到答案,于是就自己整理把。
原题简化:问输出是否某个数字比别的数字出现次数多
import java.util.*;
import static net.mindview.util.Print.*;
public class Test{
public static void main(String args[]) {
Random generate = new Random(47);
for (int i = 0; i<10000; i++) {
Integer a = generate.nextInt(20);
print(a);
}
}
}
首先:
Random 两种构造方法:
Random():创建一个新的随机数生成器。
Random(long seed):使用单个 long 种子创建一个新的随机数生成器。
疯狂测试发现
public static void main(String[] args) {
Random random = new Random();
print(random.nextInt(20));
print(random.nextInt(20));
Random random1 = new Random();
print(random1.nextInt(20));
print(random1.nextInt(20));
}
输出无规律
public static void main(String[] args) {
Random random = new Random(47);
print(random.nextInt(20));
print(random.nextInt(20));
Random random1 = new Random(47);
print(random1.nextInt(20));
print(random1.nextInt(20));
}
输出都是:18 15 18 15
下面是部分源码:
public Random(long seed) { setSeed(seed); }
//而setSeed的用法为
public void setSeed(long seed)
//使用单个 long 种子设置此随机数生成器的种子。setSeed 的常规协定是它更改此随机数生成器对象的
//状态,使其状态好像是刚刚使用参数 seed 作为种子创建它的状态一样。Random 类按如下方式实现
//setSeed 方法:
synchronized public void setSeed(long seed) {
this.seed = (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1);
haveNextNextGaussian = false;
}
//用这两个方法确定下seed,也就是基数的最终值,然后比如我们调用nextInt(20)
//那么我们来看nextInt()生成随机数的方法
public int nextInt() { return next(32); }
protected int next(int bits) {
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (int)(seed >>> (48 - bits));
}
那从上可以知道,如果你在创建一个新的Random对象的时候,赋予一个基数的话,那你生成的随机数也就是一个定值。
因为这个随机数是根据基数计算出来的。
而如果直接使用缺省构造器的话,它的基数每次都不一样。
既然如此,就写个程序把这个数字找出来
public static void main(String args[]) {
int[] num = new int[20];
int maxNum = 0, maxIndex = 0;
Random generate = new Random(47);
for (int i = 0; i < 10000; i++) {
Integer a = generate.nextInt(20);
num[a]++;
}
for (int i = 1; i < 20; i++) {
if (maxNum < num[i]) {
maxNum = num[i];
maxIndex = i;
}
}
print(maxIndex);
}
输出永远是数字9
总结:在随机次数确定且有种子的情况下,这个随机数队列是固定的。