首先想到的是Random类 查询API,JDK9里Random | RandomAccess | RandomAccessFile 可能与之有关,后两项实现list接口 和 读取写入随机访问文件.我们不需要那么复杂功能.
Random :生成伪随机数的流.
构造方法 Random(); ---应该是我们运用的目标 没有参数 很简单 .点进源码(Idea里Ctrl+鼠标左键查看)看了下 大概和现在系统时间有关系
Random(long seed) 点进源码(Idea里Ctrl+鼠标左键查看)看了下 seed具体是什么还是不太清楚.后面再验证.继续解决现在问题
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
@HotSpotIntrinsicCandidate
public static native long nanoTime();
public Random(long seed) {
if (getClass() == Random.class)
this.seed = new AtomicLong(initialScramble(seed));
else {
// subclass might have overriden setSeed
this.seed = new AtomicLong();
setSeed(seed);
}
}
private final AtomicLong seed;
public AtomicLong(long initialValue) {
value = initialValue;
}
private static long initialScramble(long seed) {
return (seed ^ multiplier) & mask;
}
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
目标明确 生成制定范围的随机数 例如:产生1个随机数 范围要求3到20.
不多说了 具体的查询API ,那么运用无参的构造(因为还不清楚seed是什么),要生成范围要求,看来和调用的方法有关.要返回的是int,那么能排除很多.其中ints(int randomNumberOrigin, int randomNumberBound) Returns an effectively unlimited stream of pseudorandom int values, each conforming to the given origin (inclusive) and bound (exclusive).大意 返回一个无限流的有效伪随机int值,每个符合给定的起始(包含)和边界(不包含).符合要求...nextInt(int bound)经过加工预计也能达到要求,另外看到
setSeed(long seed) |
|
nextInt(int bound) |
|
这两个也很感兴趣,不能直接看出怎么用.稍后再研
究
产生1个随机数 范围要求3到20.导包
import java.util.Random;
public class TestRandom {
public static void main(String[] args) {
Random A = new Random();
int m = A.ints(3, 20);
System.out.println("m=" + m);
}
}
发现报错,Error:(7, 23) java: 不兼容的类型: java.util.stream.IntStream无法转换为int.原来是"流"的问题,既然是流的问题能不能通过Integer(int value);的包装类方法来转换?emmm,想了一下 估计不行 但还是试试
int m = Integer.parseInt(A.ints(3, 20));
果然报错了.还没学到流 只是大概知道这是种输出方式...那么就换其他方法实现吧
import java.util.Random;
public class TestRandom {
public static void main(String[] args) {
Random A = new Random();
/* int m = Integer.parseInt(A.ints(3, 20));
System.out.println("m=" + m);*/
for (int i = 0; i < 10; i++) {
int n = 3 + A.nextInt(18); //min + A.nextInt(max-min+1)
System.out.println("n="+n);
}
}
}
...这种应该可行,并且总结出 min + A.nextInt (max - min +1) 可能通用,又试把条件变成3-8了下for循环100次,又运行几次,发现3出现次数偏低,并不很均等...
import java.util.Random;
public class TestRandom {
public static void main(String[] args) {
Random A = new Random();
/* int m = Integer.parseInt(A.ints(3, 20));
System.out.println("m=" + m);*/
int count = 0;
int count1 = 0;
int count7 = 0;
int count8 = 0;
for (int i = 0; i < 100; i++) {
int n = 3 + A.nextInt(5); //min + A.nextInt(max-min+1)
if (n == 3) count++;
if (n == 4) count1++;
if (n == 4) count7++;
if (n == 4) count8++;
System.out.println("n="+n);
}
System.out.println("n=3共"+count+"次");
System.out.println("n=4共"+count1+"次");
System.out.println("n=7共"+count7+"次");
System.out.println("n=8共"+count8+"次");
}
}
运行一次后统计结果:
n=3共20次
n=4共25次
n=7共25次
n=8共25次
运行二次后统计结果:
n=3共17次
n=4共24次
n=7共24次
n=8共24次
运行到第5次 统计结果 n=3 要高于其他的 ,而其他的统计结果几乎一致...
这是什么情况? 通过搜索 有很多前辈也提出了这问题并回答解决了.点击打开链接 回答的比较多 (这种方法并不太好,初始的两个数出现次数要比边界内的其他数出现概率要低,改为 下列 出现的概率要"公平"的多
int n = min + random.nextInt(max+2)%(max-min+1)
)
另外seed自己运行了一下 发现每次的随机数都是一样的 ...
Random r = new Random(100);
int a = r.nextInt();
int b =r.nextInt();
运行后,ab值不同,但运行两次 a b的值不会变化
通过搜索得到一定了解 :大意就是以前计算机内存有限,如果要产生真正的随机数是不具备条件的,设计了利用种子来生成随机数 例如种子是11,进行一系列操作:11平方,121平方,14641平方拼接得到11121146412143588881的数字,计算机每次依次取一位,近似模拟出随机效果
那么得到结论,ab都是利用种子算出来的,每次调用nextInt就算一次,重复调用值是一样的
先这样吧,等学完流再解决...