随机数生成器(RNG, random number generator)

Java 8提供了4种生成随机数的方法,如下所示:

  1. java.util.Random class
  2. Math.random method : Can Generate Random Numbers of double type.
  3. ThreadLocalRandom class
  4. java.Security.SecureRandom

1) java.util.Random

Random使用的算法是linear congruential generator (LCG 线性同余发生器).
要使用此类生成随机数,我们必须首先创建此类的实例,然后使用该实例调用 nextInt()、nextDouble()、nextLong() 等方法。
我们可以使用这个类生成整数、浮点数、双精度数、长整数、布尔值类型的随机数。
我们可以将参数传递给在要生成的数字范围上设置上限的方法。 例如,nextInt(6) 将生成 0 到 5 范围内的数字,包括两者。

// A Java program to demonstrate random number generation
// using java.util.Random;
import java.util.Random;
  
public class generateRandom{
     
  
    public static void main(String args[])
    {
     
        // create instance of Random class
        Random rand = new Random();
  
        // Generate random integers in range 0 to 999
        int rand_int1 = rand.nextInt(1000);
        int rand_int2 = rand.nextInt(1000);
  
        // Print random integers
        System.out.println("Random Integers: "+rand_int1);
        System.out.println("Random Integers: "+rand_int2);
  
        // Generate Random doubles
        double rand_dub1 = rand.nextDouble();
        double rand_dub2 = rand.nextDouble();
  
        // Print random doubles
        System.out.println("Random Doubles: "+rand_dub1);
        System.out.println("Random Doubles: "+rand_dub2);
    }
}

Random Integers: 547
Random Integers: 126
Random Doubles: 0.8369779739988428
Random Doubles: 0.5497554388209912

2) Math.random()

类 Math 包含各种数值运算的方法,例如计算幂、对数等。其中一种方法是 random(),该方法返回一个双精度值,带正号,大于或等于 0.0 且小于 1.0 . 返回值是伪随机选择的。 此方法只能生成 Doubles 类型的随机数。 下面的程序解释了如何使用这种方法:


// Java program to demonstrate working of 
// Math.random() to generate random numbers
import java.util.*;
  
public class generateRandom
{
     
    public static void main(String args[])
    {
     
        // Generating random doubles
        System.out.println("Random doubles: " + Math.random());
        System.out.println("Random doubles: " + Math.random());
    }
}

Random doubles: 0.13077348615666562
Random doubles: 0.09247016928442775

3) java.util.concurrent.ThreadLocalRandom class

这个类是在 java 1.7 中引入的,用于生成整数、双精度、布尔值等类型的随机数。 下面的程序解释了如何使用这个类来生成随机数

// Java program to demonstrate working of ThreadLocalRandom
// to generate random numbers.
import java.util.concurrent.ThreadLocalRandom;
  
public class generateRandom
{
     
    public static void main(String args[])
    {
     
        // Generate random integers in range 0 to 999
        int rand_int1 = ThreadLocalRandom.current().nextInt();
        int rand_int2 = ThreadLocalRandom.current().nextInt();
  
        // Print random integers
        System.out.println("Random Integers: " + rand_int1);
        System.out.println("Random Integers: " + rand_int2);
  
        // Generate Random doubles
        double rand_dub1 = ThreadLocalRandom.current().nextDouble();
        double rand_dub2 = ThreadLocalRandom.current().nextDouble();
  
        // Print random doubles
        System.out.println("Random Doubles: " + rand_dub1);
        System.out.println("Random Doubles: " + rand_dub2);
  
        // Generate random booleans
        boolean rand_bool1 = ThreadLocalRandom.current().nextBoolean();
        boolean rand_bool2 = ThreadLocalRandom.current().nextBoolean();
  
        // Print random Booleans
        System.out.println("Random Booleans: " + rand_bool1);
        System.out.println("Random Booleans: " + rand_bool2);
    }
}

Random Integers: 536953314
Random Integers: 25905330
Random Doubles: 0.7504989954390163
Random Doubles: 0.7658597196204409
Random Booleans: false
Random Booleans: true

4)java.Security.SecureRandom

SecureRandom默认的算法是SHA1PRNG.此类提供加密强随机数生成器 ----cryptographically secure PRNG (CSPRNG)。

SecureRandom random1 = new SecureRandom();
SecureRandom random2 = SecureRandom.getInstance("SHA1PRNG");for (int i = 0; i < 5; i++) {
     
 System.out.println(random1.nextInt() + " != " + random2.nextInt());
}

704046703 != 2117229935
60819811 != 107252259
425075610 != -295395347
682299589 != -1637998900
-1147654329 != 1418666937

性能比较:

SecureRandom比Random要慢1个数量级.

    @Test
    public void performanceCompare(){
     
        final long start = System.currentTimeMillis();
        randomInt(new Random());
        System.out.println("cost:" + (System.currentTimeMillis() - start) + "ms");

        final long start2 = System.currentTimeMillis();
        randomInt(new SecureRandom());
        System.out.println("cost:" + (System.currentTimeMillis() - start2) + "ms");
    }

    public void randomInt(Random r){
     
        final HashMap<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < 100000; i++) {
     
            final int val = r.nextInt(10);
            final Integer count = map.get(val);
            if(count == null){
     
                map.put(val, 0);
            }else{
     
                map.put(val, count + 1);
            }
            try {
     
                Thread.sleep(5);
            } catch (InterruptedException e) {
     
                e.printStackTrace();
            }
        }
        map.forEach((k,v)-> System.out.println(k+"-->"+v));
    }

0–>9968
1–>10008
2–>10003
3–>9862
4–>9975
5–>10044
6–>10247
7–>9925
8–>10001
9–>9957
cost:602079ms
0–>10150
1–>10001
2–>9960
3–>9789
4–>9973
5–>9946
6–>9958
7–>10100
8–>10024
9–>10089
cost:5024065ms


参考:
Generating random numbers in Java: https://www.geeksforgeeks.org/generating-random-numbers-in-java/

Java 生成随机数的 5 种方式,你知道几种:https://segmentfault.com/a/1190000038405773

官方文档: https://docs.oracle.com/javase/8/docs/api/java/util/Random.html
https://docs.oracle.com/javase/8/docs/api/java/security/SecureRandom.html

维基百科
https://en.wikipedia.org/wiki/Pseudorandom_number_generator
https://en.wikipedia.org/wiki/Linear_congruential_generator

你可能感兴趣的:(java,java,开发语言,后端)