thinking in java 第三章笔记及思考:奇异 操作符

  这一章相对来说简单的多,基础就不多说了,只讲新奇料点部分
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
                               于 上海 静安

猜你喜欢

转载自blog.csdn.net/u010986518/article/details/81908379
今日推荐