Java Random 随机数

转载请注明来源: http://blog.csdn.net/kjunchen/article/details/52081407

Java Random 随机数

实际开发中产生随机数的使用很常见,因此在程序中产生随机数的操作很重要。在Java中主要提供了两种方法产生随机数,分别是调用Math类的random()方法和Random类提供的产生各种数据类型的随机数的方法。

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)的随机数

下面写个示例:

public class MathRandomNumber {

    public static void main(String[] args) {
        System.out.println("Math.random()产生的随机数: " + Math.random());
        System.out.println("任意一个0~50的随机数: " + getRandomNumber(0, 50));
    }

    /**
     * 获得某个范围内的随机数
     * @param num1 起始范围参数
     * @param num2 终止范围参数
     * @return 返回num1到num2的随机数
     */
    public static int getRandomNumber(int num1, int num2) {
        return (int) (num1 + Math.random() * (num2 - num1));
    }

}

运行结果为:

Math.random()产生的随机数: 0.43653516378934365
任意一个0~50的随机数: 28

每次运行的结果都不一样。

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

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

任意两个字符之间的随机字符,可以使用如下方式:

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

示例:

public class MathRandomChar {

    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'));
    }

    //获取任意字符之间的随机字符
    public static char getRandomChar(char char1, char char2) {
        return (char)(char1 + Math.random() * (char2 - char1 + 1));
    }
}

运行结果为:

任意小写字符: g
任意大写字符: U
0~9之间任意数字: 6

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

Random类方式

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

语法如下:

Random r = new Random();

其中,r是Random对象。

以这种方式实例化对象时,Java编译器以系统当前时间作为随机数生成种子,因为每时每刻的时间不能相同,所以产生的随机数不同。

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

语法如下:

Random r = new Random(seedValue);

seedValue是随机数生成的种子。

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

实例代码:

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

运行结果如下:

随机产生一个整数: 105798029
随机产生一个大于等于0小于10的整数: 3
随机产生一个布尔型的值: false
随机产生一个浮点型的值: 0.20587307
随机产生一个双精度型的值: 0.6920970515624921
随机产生一个概率密度为高斯分布的双精度值: 0.5640177494983246

通过以上两者方式我们就可以轻松的产生我想要的随机数。

欢迎加QQ群交流: 365532949
Homepage: http://junkchen.com

众所周知,随机数是任何一种编程语言最基本的特征之一。而生成随机数的基本方式也是相同的:产生一个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.Randomjava.util.concurrent.ThreadLocalRandom就不用担心上述问题了。 Java实战项目里面介绍了一些不正确使用java.util.Random API的危害。这个教训告诉我们不要使用: 1.Math.abs(rnd.nextInt())%n 而使用: 1.rnd.nextInt(n)
参与评论 您还未登录,请先 登录 后发表或查看评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页

打赏作者

Junk Chen

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值