这一章相对来说简单的多,基础就不多说了,只讲新奇与料点部分。
1.首先我们会看到有一个生成随机数的demo,例如如下:
//生成一个数,我的是9,无论运行多少次,都是9
Random random = new Random(47);
int i = random.nextInt(10) + 1;
//生成10个数,范围(1-20),这10个数不相同,19 16 14 2 2 10 9 1 3 8 ,无论生成多少次。但是同一个种子为什么生成了10个不相同的数?也是下面的疑惑之处,也是本篇博客的精华部分
public static void getTenNumber() {
Random random = new Random(47);
int[] arr = new int[10];
for(int i = 0; i < arr.length; i++) {
arr[i] = random.nextInt(20) + 1;
}
for(int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
如果你多次运行上面的程序,你会发现生成10个固定的随机数。但是当你去掉new Random(47)里面的整数参数,结果就会是随机改变的,惊不惊喜,意不意外?
我们可以跟进其源代码(Random带参构造方法):
/**
* Creates a new random number generator using a single {@code long} seed.
* The seed is the initial value of the internal state of the pseudorandom
* number generator which is maintained by method {@link #next}.
*
* <p>The invocation {@code new Random(seed)} is equivalent to:
* <pre> {@code
* Random rnd = new Random();
* rnd.setSeed(seed);}</pre>
*
* @param seed the initial seed
* @see #setSeed(long)
*/
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 static long initialScramble(long seed) {
return (seed ^ multiplier) & mask;
}
因为其传递的是47,且multiplier、mask是static 和 final的常量,因此按理说值不变,确实打印一个值得时候结果不变。但是连续打印10个值?为什么这10个值又各不相同?意不意外?
反正我很疑惑。
Random不带参构造方法:
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
然后跳到this(seedUniquifier() ^ System.nanoTime()),也就是Random的有参构造方法。我们可以看到给的seed = seedUniquifier() ^ System.nanoTime(),seedUniquifier()方法如下,而System.nanoTime()则是把时间精确到纳秒,两个值求亦或。
根据多次运行可以看出seedUniquifier()、System.nanoTime()都是变量,seed也是变量,因此不带参数构造方法结果是随机。
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;
}
}
2.三元操作符if-else
三元操作符也称作条件操作符。
形式: Boolean表达式 ? 值1 : 值2 ;(例5 > 4 ? 5 : 4;)
优点:比if -else更加简洁
缺点:如果出现多重嵌套呢?是不是看的想吐?结构不够清晰。
2018.8.21
于 上海 静安