RandomGenerator 的默认算法即。从 JDK 18(自 17 起可用)开始,L32X64MixRandom 每次在单独调用时都会生成相同的数字。
jshell> java.util.random.RandomGenerator.getDefault().nextInt(100,999)
$10 ==> 526
jshell> java.util.random.RandomGenerator.getDefault().nextInt(100,999)
$11 ==> 526
jshell> java.util.random.RandomGenerator.of("L32X64MixRandom").nextInt(100, 999)
$14 ==> 526
jshell> java.util.random.RandomGenerator.of("L32X64MixRandom").nextInt(100, 999)
$15 ==> 526
Run Code Online (Sandbox Code Playgroud)
javadoc 听起来也没有任何特别的警告:
返回在指定原点(包括)和指定边界(不包括)之间伪随机选择的 int 值。
实现要求:默认实现检查origin 和bound 是否为正整数。然后调用 nextInt(),将结果限制为大于或等于原点且小于界限。如果bound是2的幂,那么限制就是一个简单的掩码操作。否则,通过调用 nextInt() 重新计算结果,直到结果大于或等于 origin 且小于bound。
而其他算法(包括遗留算法)似乎具有可感知的随机性水平,例如。
jshell> java.util.random.RandomGenerator.of("Random").nextInt(100,999)
$7 ==> 451
jshell> java.util.random.RandomGenerator.of("Random").nextInt(100,999)
$8 ==> 633
jshell> java.util.random.RandomGenerator.of("L64X128MixRandom").nextInt(100, 999)
$12 ==> 570
jshell> java.util.random.RandomGenerator.of("L64X128MixRandom").nextInt(100, 999)
$13 ==> 844
Run Code Online (Sandbox Code Playgroud)
默认选择的这种程度的决定论是否有原因?
编辑:行为。流非常相似,初始值似乎总是相同的
jshell> java.util.random.RandomGenerator.getDefault().ints(100,999).limit(5).toArray()
$22 ==> int[5] { 526, 860, 258, 558, 820 }
jshell> java.util.random.RandomGenerator.getDefault().ints(100,999).limit(5).toArray()
$23 ==> int[5] { 526, 866, 448, 654, 684 }
Run Code Online (Sandbox Code Playgroud)
这是https://bugs.openjdk.java.net/browse/JDK-8282551中列出的错误
它在 Java 19 中已修复,并且有一个向后移植到 Java 17 和 18 的请求(https://bugs.openjdk.java.net/browse/JDK-8284185已于 4/1/2022 解决),但尚不清楚何时将出现向后移植的修复程序。
虽然这是一个仅链接的答案,但我相信这是合适的,因为其他人会遇到这个错误并在这里搜索。
为了完整起见,这是我用于自己测试的代码:
private static String[] algs =
{"L128X1024MixRandom",
"L128X128MixRandom",
"L128X256MixRandom",
"L32X64MixRandom",
"L64X1024MixRandom",
"L64X128MixRandom",
"L64X128StarStarRandom",
"L64X256MixRandom",
"Random",
"Xoroshiro128PlusPlus",
"Xoshiro256PlusPlus"};
public static void main(String[] args) throws Exception {
for (String alg : algs)
{
System.out.println("\nAlgorithm " + alg);
for (int i=0; i<5; i++)
{
RandomGenerator g = RandomGenerator.of(alg);
System.out.println(
g.ints(4,0,1000)
.boxed()
.map(x -> String.format("%5d",x))
.collect(Collectors.joining(" ")));
}
}
}
Run Code Online (Sandbox Code Playgroud)
一次运行的输出:
Algorithm L128X1024MixRandom
280 759 35 18
824 668 554 754
822 823 680 252
629 718 3 392
83 698 609 790
Algorithm L128X128MixRandom
973 765 392 815
495 164 744 418
621 117 836 271
787 819 463 825
150 473 159 777
Algorithm L128X256MixRandom
44 74 276 107
703 802 41 743
993 369 801 926
456 754 138 870
121 979 384 51
Algorithm L32X64MixRandom
152 372 238 19
152 334 300 942
152 739 206 818
152 284 200 628
152 835 259 588
Algorithm L64X1024MixRandom
782 247 982 974
316 507 860 386
571 563 166 646
888 553 779 342
121 750 764 68
Algorithm L64X128MixRandom
706 202 985 510
761 218 252 409
992 844 765 861
236 240 124 945
680 983 444 689
Algorithm L64X128StarStarRandom
619 40 879 489
599 622 396 225
76 359 104 31
205 687 741 488
141 732 509 172
Algorithm L64X256MixRandom
929 338 648 606
786 338 409 815
750 363 713 722
989 307 18 797
154 266 20 552
Algorithm Random
903 452 417 18
838 888 609 32
365 378 673 351
758 413 665 566
996 132 555 413
Algorithm Xoroshiro128PlusPlus
145 864 592 22
230 74 24 471
596 302 294 734
108 773 171 950
716 694 87 726
Algorithm Xoshiro256PlusPlus
563 528 572 853
619 722 534 10
87 306 594 525
149 430 243 836
578 938 802 539
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
747 次 |
| 最近记录: |