初识Java(Java数字处理类-随机数)

一、随机数

    在实际开发中产生随机数的使用普遍存在,所以在程序中进行产生随机数操作很重要。在 Java 中主要提供了两种方式产生随机数,分别为调用 Math 类的 random() 方法和 Random 类提供的产生各种数据类型随机数的方法。    

    1.1  Math.random()  方法 

    在 Math 类中存在一个 random 方法,用于产生随机数字,这个方法默认生成大于等于 0.0 小于1.0 的 double 型随机数,即 0 <= Math.random() < 1.0 ,虽然 Math.random() 方法只可以产生 0 ~ 1 之间的 double 型数字,其实只要在 Math.random() 语句上稍加处理,就可以使用这个方法产生任意范围的随机数。

(int)(Math.Random() * n)           返回大于等于 0 小于 n 的随机数
m + (int)(Math.Random()  *n)       返回大于等于 m 小于 m+n (不包括 m+n )的随机数

    eg :创建类,在类中编写 GetEvenNum() 方法产生两数之间的随机数,并在主方法中输出这个随机数。

public class MathRandom {
    /**
     * 定义产生偶数的方法
     * @param num1 起始范围参数
     * @param num2 终止范围参数
     * @return 随机的范围内偶数
     */
    public static int GetEvenNum(double num1 , double num2) {
        //产生 num1 ~ num2 之间的随机数
        int s = (int)num1 + (int)(Math.random() * (num2-num1));
        if(s%2 == 0) {                                                  //判断随机数是否为偶数
        	return s;                                               //返回
        }else {                                                         //结果为奇数
        	return s + 1;                                           //将结果+1返回
        }
    }
    public static void main(String[] args) {
        //调用产生随机数方法
        System.out.println("任意一个 2 ~ 32 之间的偶数:"+GetEvenNum(2, 32));
    }
}

    运行结果为 : 

任意一个 2 ~ 32 之间的偶数:6

    每次运行大的结果都不相同,这就实现了随机产生数据的功能,病区每次产生的值都是偶数。为了实现这个功能,这里定义了一个方法 GetEvenNum() ,该方法的残花分别为产生随机数字的上限与下限。因为 m+(int)(Math.random()*n) 语句可以获取 m ~ m+n 之间的随机数,所以 “ 2+(int)(Math.random()*(32-2)) ” ,这个表达式就可以求出 2~32 之间的随机数。当获取到这个区间的随机数以后需要判断这个数字是否为偶数时,对该数字做对2取余操作即可。如果该数为奇数,则将该奇数+1 后返回也可得到偶数。

    使用 Math 类的 random() 方法也可以随机生成字符,可以使用如下代码生成 a~z 之间的字符 

(char)('a' + Math.random()*('z' - 'a' + a));

    通过上述表达式可以求出更多的随机字符,如 A ~ Z 之间的随机字符,进而推理出任意两个字符之间的随机字符,可以使用一下语句表示 :

(char)(char1 + Math.random()*(char2 - char1 + 1));

     eg : 创建类,在类中编写 GetReandomChar() 方法产生随机字符,并在主方法中输出该字符。

public class MathRandomChar {
    //定义获取任意字符之间的随机字符
    public static char GetRandomChar(char char1, char char2) {
        return (char)(char1 + Math.random()*(char2 - char1 + 1));
    }
    public static void main(String[] args) {
        //获取 a~z 之间的随机字符
        System.out.println("任意小写字符:" + GetRandomChar('a', 'z'));
        //获取 A~Z 之间的随机字符
        System.out.println("任意大写字符:" + GetRandomChar('A', 'Z'));
        //获取 0~9 之间的随机字符
        System.out.println("0 到 9 任意数字字符:" + GetRandomChar('0', '9'));
    }
}

    运行结果为 :

任意小写字符:l
任意大写字符:P
0 到 9 任意数字字符:1

    random() 方法返回的值实际上是伪随机数,它通过复杂的运算而得到一系列的数。该方法时通过当前时间作为随机数生成器的参数,所以每次执行程序都会产生不同的随机数。

    1.2  Random  类

    除了 Math 类中的 random() 方法可以获取随机数之外, Java 中还提供了一种可以获取随机数的方式,那就是 java.util.Random 类。可以通过实例化一个 Random 对象创建一个随机数生成器。

    语法如下 :

Random r = new Random(); 

    其中 : r    是指 Random 对象。

    以这种方式实例化对象时, Java 编译器以系统当前时间作为随机数生成器的种子,因为每时每刻的时间不可能相同,所以产生的随机数将不同,但是如果运行速度太快,也会产生两次运行结果相同的随机数。

    同时也可以在实例化 Random 对象时,设置随机数生成器的种子。

    语法如下 :

Random r = new Random(seedValue);
    r  : Random 类对象

    seedValue  :随机数生成器的种子

    在 Random 类中提供了获取各种数据类型随机数的方法,下面列举几个常用的方法:

public int nextInt() :             返回一个随机整数
public int nextInt(int n) :        返回大于等于 0 小于 n 的随机整数
public long nextLong() :           返回一个随机长整型值
public boolean nextBoolean() :     返回一个随机布尔型值
public float nextFloat() :         返回一个随机浮点型值
public double nextDouble() :       返回一个随机双精度型值
public double nexGaussian() :      返回一个概率密度为高斯分布的双精度值

    eg : 创建类,在累的主方法中创建 Random 的对象,使用该对象生成各种类型的随机数,并输出结果。

import java.util.Random;                                               //导包
public class RandomDemo {
public static void main(String[] args) {
Random random = new Random();                                          //实例化一个 Random 类
System.out.println("随机产生一个整数:" + random.nextInt());
System.out.println("随机产生一个大于等于 0 小于 10 的整数:" + random.nextInt(10));
System.out.println("随机产生一个布尔型值:" + random.nextBoolean());
System.out.println("随机产生一个双精度型的值:" + random.nextDouble());
System.out.println("随机产生一个浮点型的值:" + random.nextFloat());
System.out.println("随机产生一个概率密度为高斯分布的双精度值:" + random.nextGaussian());
}
}

    运行结果为:

随机产生一个大于等于 0 小于 10 的整数:5
随机产生一个布尔型值:false
随机产生一个双精度型的值:0.4923202923804435
随机产生一个浮点型的值:0.6521005
随机产生一个概率密度为高斯分布的双精度值:-0.2458356560206751




  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
众所周知,随机数是任何一种编程语言最基本的特征之一。而生成随机数的基本方式也是相同的:产生一个0到1之间的随机数。看似简单,但有时我们也会忽略了一些有趣的功能。 我们从书本上学到什么? 最明显的,也是直观的方式,在Java中生成随机数只要简单的调用: 1.java.lang.Math.random() 在所有其他语言中,生成随机数就像是使用Math工具,如abs, pow, floor, sqrt和其他数学函数。大多数人通过书籍、教程和课程来了解这个。一个简单的例子:从0.0到1.0之间可以生成一个双精度浮点数。那么通过上面的信息,开发人员要产生0.0和10.0之间的双精度浮点数会这样来写: 1.Math.random() * 10 而产生0和10之间的整数,则会写成: 1.Math.round(Math.random() * 10) 进阶 通过阅读Math.random()的源码,或者干脆利用IDE的自动完成功能,开发人员可以很容易发现,java.lang.Math.random()使用一个内部的随机生成对象 - 一个很强大的对象可以灵活的随机产生:布尔值、所有数字型,甚至是高斯分布。例如: 1.new java.util.Random().nextInt(10) 它有一个缺点,就是它是一个对象。它的方法必须是通过一个实例来调用,这意味着必须先调用它的构造函数。如果在内存充足的情况下,像上面的表达式是可以接受的;但内存不足时,就会带来问题。 一个简单的解决方案,可以避免每次需要生成一个随机数时创建一个新实例,那就是使用一个静态。猜你可能想到了java.lang.Math,很好,我们就是改良java.lang.Math的初始化。虽然这个工程量低,但你也要做一些简单的单元测试来确保其不会出错。 假设程序需要生成一个随机数来存储,问题就又来了。比如有时需要操作或保护种子(seed),一个内部数用来存储状态和计算下一个随机数。在这些特殊情况下,共用随机生成对象是不合适的。 并发 在Java EE多线程应用程序的环境中,随机生成实例对象仍然可以被存储在或其他实现,作为一个静态属性。幸运的是,java.util.Random是线程安全的,所以不存在多个线程调用会破坏种子(seed)的风险。 另一个值得考虑的是多线程java.lang.ThreadLocal的实例。偷懒的做法是通过Java本身API实现单一实例,当然你也可以确保每一个线程都有自己的一个实例对象。 虽然Java没有提供一个很好的方法来管理java.util.Random的单一实例。但是,期待已久的Java 7提供了一种新的方式来产生随机数: 1.java.util.concurrent.ThreadLocalRandom.current().nextInt(10) 这个新的API综合了其他两种方法的优点:单一实例/静态访问,就像Math.random()一样灵活。ThreadLocalRandom也比其他任何处理高并发的方法要更快。 经验 Chris Marasti-Georg 指出: 1.Math.round(Math.random() * 10) 使分布不平衡,例如:0.0 - 0.499999将四舍五入为0,而0.5至1.499999将四舍五入为1。那么如何使用旧式语法来实现正确的均衡分布,如下: 1.Math.floor(Math.random() * 11) 幸运的是,如果我们使用java.util.Random或java.util.concurrent.ThreadLocalRandom就不用担心上述问题了。 Java实战项目里面介绍了一些不正确使用java.util.Random API的危害。这个教训告诉我们不要使用: 1.Math.abs(rnd.nextInt())%n 而使用: 1.rnd.nextInt(n)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值