Random类

内容纲要
Random类

Random类位于java.util包下,Random类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字。

相同种子数的Random对象,相同次数生成的随机数字是完全相同的。也就是说,两个种子数相同的Random对象,第一次生成的随机数字完全相同,第二次生成的随机数字也完全相同。这点在生成多个随机数字时需要特别注意。

Random对象的生成

Random类包含两个构造方法,下面依次进行介绍:

public Random()  

该构造方法使用一个和当前系统时间对应的相对时间有关的数字作为种子数,然后使用这个种子数构造Random对象。

public Random(long seed)  

该构造方法可以通过制定一个种子数进行创建。

示例代码:

Random r = new Random();  
Random r1 = new Random(10); 

再次强调:种子数只是随机算法的起源数字,和生成的随机数字的区间无关。

验证:相同种子数的Random对象,相同次数生成的随机数字是完全相同的。

package educoder;
import java.util.Random;
public class RandomTest {  
   public void random() {  
       int i = 0;  
       int j = 0;  
       Random random = new Random(1);  
       Random random1 = new Random(1);  
       i = random.nextInt();  
       j = random1.nextInt();  
       System.out.println("i:" + i + "\nj:" + j);  
  }
   public static void main(String[] args) {  
       RandomTest tt = new RandomTest();  
       tt.random();  
  }
}  

输出结果:

第一次:

i:-1155869325
j:-1155869325

修改一下起源数字,让其等于100。

Random random = new Random(100);  
Random random1 = new Random(100);  

输出结果: i:-1193959466 j:-1193959466

Random类中的常用方法

Random类中的方法比较简单,每个方法的功能也很容易理解。需要说明的是,Random类中各方法生成的随机数字都是均匀分布的,也就是说区间内部的数字生成的几率是均等的。下面对这些方法做一下基本的介绍:

package educoder;
import java.util.Random;
public class RandomTest {  
   public static void main(String[] args) {  
       Random random = new Random();  
       System.out.println("nextInt():" + random.nextInt()); // 随机生成一个整数,这个整数的范围就是int类型的范围-2^31~2^31-1  
       System.out.println("nextLong():" + random.nextLong()); // 随机生成long类型范围的整数  
       System.out.println("nextFloat():" + random.nextFloat()); // 随机生成[0, 1.0)区间的小数  
       System.out.println("nextDouble():" + random.nextDouble()); // 随机生成[0, 1.0)区间的小数  
       System.out.println("nextBoolean():"+random.nextBoolean());//随机生成一个boolean值,生成true和false的值几率相等,也就是都是50%的几率  
       System.out.println("nextGaussian():"+random.nextGaussian());//随机生成呈高斯(“正态”)分布的 double 值,其平均值是 0.0,标准差是 1.0  
       byte[] byteArr = new byte[5];  
       random.nextBytes(byteArr); // 随机生成byte,并存放在定义的数组中,生成的个数等于定义的数组的个数  
       System.out.print("nextBytes():");  
       for (int i = 0; i < byteArr.length; i++) {  
               System.out.print(byteArr[i]+"\t");  
      }  
       System.out.println();
       /**  
        * random.nextInt(n)  
        * 随机生成一个正整数,整数范围[0,n),包含0而不包含n  
        * 如果想生成其他范围的数据,可以在此基础上进行加减  
        *  
        * 例如:  
        * 1. 想生成范围在[0,n]的整数  
        *         random.nextInt(n+1)  
        * 2. 想生成范围在[m,n]的整数, n > m  
        *         random.nextInt(n-m+1) + m  
        *         random.nextInt() % (n-m) + m  
        * 3. 想生成范围在(m,n)的整数  
        *         random.nextInt(n-m+1) + m -1  
        *         random.nextInt() % (n-m) + m - 1  
        * ......主要是依靠简单的加减法  
        */  
       System.out.println("nextInt(10):" + random.nextInt(10)); // 随机生成一个整数,整数范围[0,10)  
       for (int i = 0; i < 5; i++) {  
           System.out.println("我生成了一个[3,15)区间的数,它是:" + (random.nextInt(12) + 3));  
      }  
       /**  
        * random.nextDouble()  
        * 例如:  
        * 1.生成[0,1.0)区间的小数  
        *         double d1 = random.nextDouble();//直接使用nextDouble方法获得。  
        * 2.生成[0,5.0)区间的小数  
        *           double d2 = random.nextDouble() * 5;//因为扩大5倍即是要求的区间。同理,生成[0,d)区间的随机小数,d为任意正的小数,则只需要将nextDouble方法的返回值乘以d即可。  
        * 3.生成[1,2.5)区间的小数  
        *         double d3 = r.nextDouble() * 1.5 + 1;//生成[1,2.5)区间的随机小数,则只需要首先生成[0,1.5)区间的随机数字,然后将生成的随机数区间加1即可。  
        * ......同理,生成任意非从0开始的小数区间[d1,d2)范围的随机数字(其中d1不等于0),则只需要首先生成[0,d2-d1)区间的随机数字,然后将生成的随机数字区间加上d1即可。  
        *  
        */  
      }  
}  

输出结果:

nextInt():1842341002

“nextLong():4006643082448092921

“nextFloat():0.88948154

nextDouble():0.5635189241159165
nextBoolean():false

“nextGaussian():1.3191426544832998

“nextBytes():36 100 94 14 -98

nextInt(10):1
我生成了一个[3,15)区间的数,它是:5
我生成了一个[3,15)区间的数,它是:10
我生成了一个[3,15)区间的数,它是:10
我生成了一个[3,15)区间的数,它是:11
我生成了一个[3,15)区间的数,它是:6

JDK1.8新增方法:

package educoder;
import java.util.Random;
public class RandomTest2 {  
   /**  
    * 测试Random类中 JDK1.8提供的新方法 JDK1.8新增了Stream的概念 在Random中,为double, int,  
    * long类型分别增加了对应的生成随机数的方法 鉴于每种数据类型方法原理是一样的,所以,这里以int类型举例说明用法  
    */
   public static void main(String[] args) {  
       Random random = new Random();  
       random.ints(); // 生成无限个int类型范围内的数据,因为是无限个,这里就不打印了,会卡死的......  
       random.ints(10, 100); // 生成无限个[10,100)范围内的数据
       /**  
        * 这里的toArray 是Stream里提供的方法  
        */  
       int[] arr = random.ints(5).toArray(); // 生成5个int范围类的整数。  
       System.out.println(arr.length);  
       for (int i = 0; i < arr.length; i++) {  
           System.out.println(arr[i]);  
      }
       // 生成5个在[10,100)范围内的整数  
       arr = random.ints(5, 10, 100).toArray();  
       for (int i = 0; i < arr.length; i++) {  
           System.out.println(arr[i]);  
      }
       /**  
        * 对于 random.ints(); random.ints(ori, des);  
        * 两个生成无限个随机数的方法,我们可以利用Stream里的terminal操作,来截断无限这个操作  
        */  
       // limit表示限制只要5个,等价于random.ints(5)  
       arr = random.ints().limit(5).toArray();  
       System.out.println(arr.length);  
       for (int i = 0; i < arr.length; i++) {  
           System.out.println(arr[i]);  
      }
       // 等价于random.ints(5, 10, 100)  
       arr = random.ints(10, 100).limit(5).toArray();  
       for (int i = 0; i < arr.length; i++) {  
           System.out.println(arr[i]);  
      }  
  }
}  

输出结果: 5 1801462452 -1812435985 -1073912930 1160255210 -1342018704 80 54 16 67 82 5 -1161610558 283052091 797550518 -275356995 -1661722790 11 27 27 52 54

package case4;

//密码的自动生成器:密码由大写字母/小写字母/数字组成,生成六位随机密码
import java.util.Random;
import java.util.Scanner;

public class RandomTest {
   public static void main(String[] args) {
       // 定义一个字符型数组
       char[] pardStore = new char[62];
       // 把所有的大写字母放进去 把所有的小写字母放进去 把0到9放进去
       /********* Begin *********/

       for(int i=0;i<26;i++) {
           pardStore[i] = (char)(i+65);
      }
       for(int i=26;i<52;i++) {
           pardStore[i] = (char)(i+71);
      }
       for(int i=0;i<10;i++) {
           pardStore[i+52] = (char)(i+48);
      }
       /********* End *********/
       // 分别以1、2、3作为种子数 生成6位随机密码
       Scanner sc = new Scanner(System.in);
       int seed = sc.nextInt();
       Random random = new Random(seed);
       int n;
       /********* Begin *********/
       for (int i = 0; i < 6; i++) {
           n=random.nextInt(62);
           System.out.print(pardStore[n]);
      }
       /********* End *********/
  }
}

一条评论

  1. Good post. I learn something new and challenging on sites I stumbleupon everyday. Its always interesting to read articles from other authors and practice something from other sites.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注