Java随机数生成Random类​使用示例

Java随机数生成Random类

  • Random类

java.Util.Random类,此类的一个实例用于生成伪随机数流,如果使用相同的种子创建了两个Random实例,并且对每个实例进行了相同的方法调用序列,则它们将生成并返回相同的数字序列。

java.util.Random 的实例是线程安全的。但是,在多个线程中并发使用同一个java.util.Random实例可能会遇到争用问题,从而导致性能不佳。可以考虑在多线程设计中使用java.util.concurrent.ThreadLocalRandom类。

java.util.Random的实例在加密方面并不安全。可以考虑使用java.security.SecureRandom来获取加密安全的伪随机数生成器,以供安全敏感的应用程序使用。

  • 构造方法
  1. public Random()

创建一个新的随机数生成器。此构造函数将随机生成一个种子,它的值很可能与此构造函数的其他任何调用者使用的值都不相同(确保种子的唯一性)。

  1. public Random(long seed)

使用单个长种子创建新的随机数生成器。种子是由next方法维护的伪随机数生成器内部状态的初始值。

调用 new Random(seed) 等同于:

Randomrnd = new Random();

rnd.setSeed(seed);

常提供的seed有:

System.currentTimeMillis(); //本机当前的毫秒值

System.nanoTime(); //本机当前的纳秒值

如果使用相同的种子创建了两个 Random 实例,并且对每个实例进行了相同的方法调用序列,则它们将生成并返回相同的数字序列。如下两个Random的对象r1和r2使用相同的seed,故它们生成的随机数是一样的,代码:

public class RandDemo {
    public static void main(String[] args) {

        // 系统当前毫秒值,也可用System.nanoTime()
        long seed = System.currentTimeMillis();
        // 创建Random对象r1
        Random r1 = new Random(seed);
        // 创建Random对象r2
        Random r2 = new Random(seed);
        // r1和r2生成10个相同的伪随机数
        for (int i = 0; i < 3; i++) {
            System.out.println("======第" + (i + 1) + "次======");
            System.out.println(r1.nextInt());
            System.out.println(r2.nextInt());
        }
        /* 笔者在运行这段代码时的输出:
            ======第1次======
            -1705500708
            -1705500708
            ======第2次======
            1375764432
            1375764432
            ======第3次======
            -2111979661
            -2111979661
        */
    }
}

所以,要知晓Random对象的伪随机特性,随机只是表明调用随机方法时生成的数是按相等概率分布的,并不代表不能被预测,否则就是真随机数了,而这在计算机里是做不到的。

  • 常用方法
  1. public int nextInt()

此方法返回此随机数生成器序列中的下一个伪随机均匀分布的int值。nextInt的一般约定是生成并返回一个int值。

返回值:这个随机数生成器序列中的下一个伪随机均匀分布的int值,即int范围内的任一随机数。

  1. public int nextInt(int bound)

返回一个伪随机、均匀分布的整数值,该值在0(包括)和指定值bound(不包括)之间,从该随机数生成器的序列中抽取。nextInt的通用约定是,在指定范围内,一个int值是伪随机生成并返回的。所有可能的 int 值都是以(近似)相等的概率产生的。

参数:bound – 上限(不包括上限)。必须为正数。

范围值:下一个伪随机、均匀分布的整数值,介于此随机数生成器序列的零(包括)和边界(不包括)之间

举例:

Random r = new Random();
// 生成一个0-100的整数值
int randNum1 = r.nextInt(101);
// 生成一个1-100之间的整数值
int randNum2 = r.nextInt(100) + 1;

System.out.println(randNum1);
System.out.println(randNum2);

此外还有nextLong()、nextBoolean()、nextFloat()、nextDouble()方法。

  • Math.random()方法

java.lang.Math.random()方法,其本质就是调用Random类的nextDouble()方法。

本方法返回一个带有正号的双精度值,大于或等于0.0(包含)并小于1.0(不包含)。返回的值是(近似)均匀分布在该范围内的伪随机值。

当首次调用此方法时,它会创建一个新的伪随机数生成器,如下:

new java.util.Random()

此后,此新的伪随机数生成器用于对此方法的所有调用,并且不用于其他任何地方。

此方法已正确同步,允许多个线程正确使用。但是,(由于底层就是使用Random类,所以其特性与Random一样)如果许多线程需要以极高的速率生成伪随机数,则每个线程拥有自己的伪随机数生成器可能会减少争用,此时应考虑使用java.util.concurrent.ThreadLocalRandom类。

  • 应用

返回指定范围的随机数min(包含)到max(不包含)之间的公式:

Math.random() * (max-min) + min;

如下示例方法:

public class RandDemo2 {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            //System.out.println(getRandom());
            //System.out.println(getRandomArbitrary(0, 100));
            //System.out.println(getRandomInt(0, 100));
            //System.out.println(getRandomIntInclusive(1, 100));
            //System.out.println(getRandomLowercaseLetter());
            System.out.println(getRandomVisibleCharacter());

        }
    }

    /**
     * 得到一个大于等于 0,小于 1 之间的随机double类型的数
     * @return 返回[0,1)之间的一个随机double值
     */
    public static double getRandom() {
        return Math.random();
    }

    /**
     * 得到一个两数之间的随机数
     * 这个例子返回了一个在指定值之间的随机数。
     * 这个值在 min(包含)与max(不包含)之间。
     * @param min 下区间(包含)
     * @param max 上区间(不包含)
     * @return 返回[min,max)区间内的double值
     */
    public static double getRandomArbitrary(int min, int max) {
        return (Math.random() * (max - min) + min);
    }

    /**
     * 这个例子返回了一个在指定值之间的随机整数。
     * 这个值不小于 min (包含),且小于(不包含)max。
     * @param min 下区间(包含)
     * @param max 上区间(不包含)
     * @return 在[min,max)区间内的随机整数
     */
    public static int getRandomInt(int min, int max) {
        return (int) (Math.floor(Math.random() * (max - min)) + min); //不含最大值,含最小值
    }

    /**
     * 上一个例子提到的函数 getRandomInt() 结果范围包含了最小值,但不含最大值。
     * 如果你的随机结果需要同时包含最小值和最大值,怎么办呢?
     * getRandomIntInclusive() 函数可以实现。
     * @param min 下区间(包含)
     * @param max 上区间(不包含)
     * @return 在[min,max]区间内的随机整数
     */
    public static int  getRandomIntInclusive(int min, int max) {
        return (int) (Math.floor(Math.random() * (max - min + 1)) + min); //含最大值,含最小值
    }

    /**
     * 生成一个ASCII码表中随机小写字母,a-z之间
     * @return 生成一个随机字符a-z之间
     */
    public static char getRandomLowercaseLetter(){
        return (char) (Math.random() * ('z' - 'a' + 1) + 'a');
    }

    /**
     * 生成一个ASCII码表中的!到~之间的可见字符
     * @return 生成一个ASCII码表中的!到~之间的可见字符
     */
    public static char getRandomVisibleCharacter(){
        return (char) (Math.random() * ('~' - '!' + 1) + '!');
    }
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐骁虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值