77百科网
当前位置: 首页 生活百科

java中random和if组合用法(Javarandom随机数)

时间:2023-06-06 作者: 小编 阅读量: 1 栏目名: 生活百科

java中random和if组合用法伪随机:通过算法产生的随机数都是伪随机!!只有通过真实的随机事件产生的随机数才是真随机!!比如,通过机器的硬件噪声产生随机数、通过大气噪声产生随机数Random生成的随机数都是伪随机数!!!是由可确定的函数,通过一个种子,产生的伪随机数。每遍输出的多个序列均不同。Random用种子seed构造一个随机数生成器,种子是给定的。

java中random和if组合用法?伪随机(preundorandom):通过算法产生的随机数都是伪随机,现在小编就来说说关于java中random和if组合用法?下面内容希望能帮助到你,我们来一起看看吧!

java中random和if组合用法

伪随机(preundorandom):通过算法产生的随机数都是伪随机!!

只有通过真实的随机事件产生的随机数才是真随机!!比如,通过机器的硬件噪声产生随机数、通过大气噪声产生随机数

Random生成的随机数都是伪随机数!!!

是由可确定的函数(常用线性同余),通过一个种子(常用时钟),产生的伪随机数。这意味着:如果知道了种子,或者已经产生的随机数,都可能获得接下来随机数序列的信息(可预测性)

Random类拥有两个构造方法,用于实现随机数生成器:

    Random( ) 构造一个随机数生成器,种子是 与nanoTime异或后的值。每遍输出的多个序列均不同。随机性更强。

    Random(long seed) 用种子seed构造一个随机数生成器,种子是给定的。每遍输出的多个序列均相同。

源码:

/*** Creates a new random number generator. This constructor sets* the seed of the random number generator to a value very likely* to be distinct from any other invocation of this constructor.*/public Random() {this(seedUniquifier() ^ System.nanoTime());//与System.nanoTime()异或//这里System.nanoTime();并不是以纳秒为单位的系统时间,只用来计算花费多少时间用的。与时间的概念无关。}private static long seedUniquifier() {// L'Ecuyer, "Tables of Linear Congruential Generators of// Different Sizes and Good Lattice Structure", 1999for (;;) {long current = seedUniquifier.get();long next = current * 181783497276652981L;if (seedUniquifier.compareAndSet(current, next))return next;}}private static final AtomicLong seedUniquifier= new AtomicLong(8682522807148012L); //种子分配器/*** Creates a new random number generator using a single {@code long} seed.* The seed is the initial value of the internal state of the pseudorandom* number generator which is maintained by method {@link #next}.** <p>The invocation {@code new Random(seed)} is equivalent to:*<pre> {@code* Random rnd = new Random();* rnd.setSeed(seed);}</pre>** @param seed the initial seed* @see#setSeed(long)*/public Random(long seed) {//无参构造,有参构造,均是调用这个方法if (getClass() == Random.class)// Random random1 = new Random();或者Random random2 = new Random(100); 均是调用这个ifthis.seed = new AtomicLong(initialScramble(seed));//处理后,seed值没变else {// subclass might have overriden setSeedthis.seed = new AtomicLong();setSeed(seed);}}private static long initialScramble(long seed) {return (seed ^ multiplier) & mask;}

一、无参构造方法(不设置种子)

虽然表面上看我们未设置种子,但Random构造方法里有一套自己的种子生成机制,源码如上。

生成种子过程:(参考解密随机数生成器(二)——从java源码看线性同余算法)

    获得一个长整形数作为“初始种子”(系统默认的是8682522807148012L)

    不断与一个变态的数——181783497276652981L相乘(天知道这些数是不是工程师随便滚键盘滚出来的-.-)得到一个不能预测的值,直到 能把这个不能事先预期的值 赋给Random对象的静态常量seedUniquifier 。因为多线程环境下赋值操作可能失败,就for(;;)来保证一定要赋值成功

    与系统随机出来的nanotime值作异或运算,得到最终的种子

nanotime算是一个随机性比较强的参数,用于描述代码的执行时间。源码中关于nanotime的描述(部分):

并不是以纳秒为单位的系统时间,只用来计算花费多少时间用的。与时间的概念无关。

/*** Returns the current value of the running Java Virtual Machine's* high-resolution time source, in nanoseconds.** <p>This method can only be used to measure elapsed time and is* not related to any other notion of system or wall-clock time.* The value returned represents nanoseconds since some fixed but* arbitrary <i>origin</i> time (perhaps in the future, so values* may be negative).The same origin is used by all invocations of* this method in an instance of a Java virtual machine; other* virtual machine instances are likely to use a different origin.** <p>This method provides nanosecond precision, but not necessarily* nanosecond resolution (that is, how frequently the value changes)* - no guarantees are made except that the resolution is at least as* good as that of {@link #currentTimeMillis()}.** <p>Differences in successive calls that span greater than* approximately 292 years (2<sup>63</sup> nanoseconds) will not* correctly compute elapsed time due to numerical overflow.** <p>The values returned by this method become meaningful only when* the difference between two such values, obtained within the same* instance of a Java virtual machine, is computed.** <p> For example, to measure how long some code takes to execute:*<pre> {@code* long startTime = System.nanoTime();* // ... the code being measured ...* long estimatedTime = System.nanoTime() - startTime;}</pre>** <p>To compare two nanoTime values*<pre> {@code* long t0 = System.nanoTime();* ...* long t1 = System.nanoTime();}</pre>** one should use {@code t1 - t0 < 0}, not {@code t1 < t0},* because of the possibility of numerical overflow.** @return the current value of the running Java Virtual Machine's*high-resolution time source, in nanoseconds* @since 1.5*/public static native long nanoTime();

二、有参构造方法(设置种子)

语法:Random ran = Random(long seed)

有参构造方法的源码如上。

其中的multiplier和mask都是定值:

private static final long multiplier = 0x5DEECE66DL;private static final long mask = (1L << 48) - 1;

三、代码测试

分别采用有参和无参两种方法,生成[0, 100)内的随机整数,各生成五组,每组十个随机数:

import java.util.Random;public class RandomTest {public static void main(String[] args) {RandomTest rt = new RandomTest();rt.testRandom();}public void testRandom(){System.out.println("Random不设置种子:");for (int i = 0; i < 5; i) {Random random = new Random();for (int j = 0; j < 10; j) {System.out.print(" "random.nextInt(100)", ");}System.out.println("");}System.out.println("");System.out.println("Random设置种子:");for (int i = 0; i < 5; i) {Random random = new Random();random.setSeed(100);for (int j = 0; j < 10; j) {System.out.print(" "random.nextInt(100)", ");}System.out.println("");}} }

运行结果如下:

结论:

虽然二者都是伪随机,但是,无参数构造方法(不设置种子)具有更强的随机性,能够满足一般统计上的随机数要求。使用有参的构造方法(设置种子)无论你生成多少次,每次生成的随机序列都相同,名副其实的伪随机!!

四、为何要使用种子?

种子就是生成随机数的根,就是产生随机数的基础。计算机的随机数都是伪随机数,以一个真随机数(种子)作为初始条件,然后用一定的算法不停迭代产生随机数。Java项目中通常是通过Math.random方法和Random类来获得随机数。

Random类中不含参构造方法每次都使用当前时间作为种子,而含参构造方法是以一个固定值作为种子。

随机数是种子经过计算生成的。

不含参的构造函数每次都使用当前时间作为种子,随机性更强

随机数的生成是从种子值开始。 如果反复使用同一个种子,就会生成相同的数字系列,产生不同序列的一种方法是使种子值与时间相关。

五、System.nanoTime()

System.out.println(System.nanoTime());//并不是以纳秒为单位的系统时间System.out.println(System.nanoTime());System.out.println(System.nanoTime());System.out.println(System.currentTimeMillis());//第一遍运行://281092180853691//281092180911666//281092180936920//1610767387212=>2021-01-16 11:23:07//第二遍运行://281207286912695//281207286952070//281207286970745//1610767502318

以上运行、源码基于jdk1.8

end

    推荐阅读
  • 白夜行一样好看的小说(白夜行终于读完了)

    警方在她家发现了吃过之后丢弃的包装盒,于是警方断定桐原洋介那天来过雪穗家。西本母女两人居住,雪穗的父亲七年前在工地上发生意外去世了。警方猜测桐原洋介和西本文代的关系不一般,不巧的是西本文代却有完美的不在场的证明。寺崎忠夫承认了他和西本文代确实在交往。这时的警方,推测桐原洋介可能是胁迫西本文代,而寺崎忠夫无法忍受,便将其杀害的,又不巧的是,这个时候,寺崎忠夫发生了意外,疲劳驾驶意外死亡。

  • 昀怎么读什么意思(昀读音和解释)

    跟着小编一起来看一看吧!昀怎么读什么意思昀是一个汉语汉字,读音为yún。释义为日光,出自于《玉篇》――昀,日光也。多用于人名,纪昀,即纪晓岚。《玉篇》日光也。昀部首:日昀笔画:8

  • 屋顶被火球砸死(神秘火球坠落挪威首都)

    NMN当地时间7月25日午夜,挪威首都奥斯陆的一些市民被空中传来的巨响惊醒。研究人员推测,这个火球是一颗火流星。根据监控,研究人员推断这颗火流星最终落入了距奥斯陆市区约60公里的Finnemarka森林中,并在流星坠落后进行了搜寻。这颗火流星的本体有卡车般大,释放出的能量相当于广岛原子弹爆炸的30倍左右。它坠落后给当地的建筑造成了一定程度的破坏,并使大约1200人不同程度地受伤神秘火球午夜坠落挪威的森林。

  • 帝豪s和帝豪gs有什么区别(帝豪s跟帝豪gs)

    近日,小编经常收到小伙伴们关于“帝豪S和帝豪GS有什么区别”的相关留言,现在为大家讲解。帝豪s和帝豪gs都是吉列汽车旗下的SUV车型。帝豪s和帝豪gs两者的主要区别在于:1,产品售价对比,帝豪s的定价比帝豪gs稍微高一些;2,产品定位对比,帝豪s虽然跟帝豪gs在车型还有很多方面很类似,但是帝豪s更注重在年轻运动、时尚感、科技感方面的品牌升级。买车究竟是买轿车好呢?其实,这个关键还是要看买车的目的是什么。

  • 普通翡翠怎么让它水头好点(如果你不懂翡翠的)

    当欣赏翡翠的水头时,联想起女人如水这句话,都有那么一种类似的感觉,清新雅致,显得是那样的纯净而动人、单纯、和平之美别具韵味。水头是翡翠业内的行家通过长时期的观察总结出来的一种比拟性的表述。说到翡翠的水头,大家都知道透明度好的翡翠,水头就好,水头就是翡翠的透明度,这种说法不完全正确。水头的好坏直接关系到成品的质量,是评价翡翠的重要因素之一。

  • 鲜红的太阳在徐徐上升改成比喻句(什么是比喻句)

    我们一起去了解并探讨一下这个问题吧!鲜红的太阳在徐徐上升改成比喻句徐徐上升的太阳像鲜红的一团火。鲜红的太阳在徐徐上升,像一个硕大的火球。比喻句,是一种常用修辞手法,意思是打比方,用浅显、具体、生动的事物来代替抽象、难理解的事物。

  • 金乡定亲风俗(文化费县之婚嫁习俗篇)

    费县民间关于婚嫁的习俗讲究也特别多,操办起来也是力求热闹。不过了解费县这些习俗还是很有意义的,既是对传统文化的传承,很多礼节的设定本来也具有实用价值。费县的很多婚嫁习俗也是这样,看似落后的无价值的仪式,有一部分因为生活习惯变化太大没有操作必要了,但大部分还是有价值的。今天首先介绍费县婚嫁习俗当中的定亲仪式,明天介绍送日子习俗,欢迎继续关注。

  • 隔离乳可以直接涂吗(怎么使用)

    隔离乳的主要作用是隔绝皮肤和彩妆,以及空气中的污染物,虽然它里面也含有一定物质,可以滋养肌肤,但单靠这些是不能够满足肌肤要求的,所以在使用隔离乳之前要做好基础护肤工作。一般情况下最简单的步骤是在使用完爽肤水以及乳液之后涂抹隔离乳,如果是本身肌肤比较容易出油,或是夏天容易出汗的情况下,可以选择拍完水之后使用隔离乳。隔离乳的主要作用是保护肌肤,使用完隔离乳之后,就可以使用其他彩妆产品了。

  • 等一个人的说说(20条等一个人的说说心情短语)

    死缠烂打的样子特别丑,所以我选择自己走。如果有一天,我走进你的心里,我也会哭,因为那里没有我。

  • 要请病假的证明怎么开?(请病假需要怎么开证明)

    第三条企业职工因患病或非因工负伤,需要停止工作医疗时,根据本人实际参加工作年限和在本单位工作年限,给予三个月到二十四个月的医疗期:(一)实际工作年限十年以下的,在本单位工作年限五年以下的为三个月;五年以上的为六个月。