<h2 id="toc_0">随机数 Int 的生成</h2>
<h3 id="toc_1">生成无边界的 Int</h3>
@Test
public void testRandom_generatingIntegerUnbounded() throws Exception {
int intUnbounded = new Random().nextInt();
System.out.println(intUnbounded);
}
</code></pre>
<h3 id="toc_2">生成有边界的 Int</h3>
@Test
public void testRandom_generatingIntegerBounded_withRange() throws Exception {
int min = 1;
int max = 10;
int intBounded = min + ((int) (new Random().nextFloat() * (max - min)));
System.out.println(intBounded);
}
</code></pre>
<blockquote>
<p>包含 1 而不包含 10</p>
</blockquote>
<h3 id="toc_3">使用 Apache Common Math 来生成有边界的 Int</h3>
@Test
public void testRandom_generatingIntegerBounded_withApacheMath() throws Exception {
int min = 1;
int max = 10;
int intBounded = new RandomDataGenerator().nextInt(min, max);
System.out.println(intBounded);
}
</code></pre>
<blockquote>
<p>包含 1 且包含 10</p>
</blockquote>
<h3 id="toc_4">使用 Apache Common Lang 的工具类来生成有边界的 Int</h3>
@Test
public void testRandom_generatingIntegerBounded_withApacheLangInclusive() throws Exception {
int min = 1;
int max = 10;
int intBounded = RandomUtils.nextInt(min, max);
System.out.println(intBounded);
}
</code></pre>
<blockquote>
<p>包含 1 而不包含 10</p>
</blockquote>
<h3 id="toc_5">使用 TreadLocalRandom 来生成有边界的 Int</h3>
@Test
public void testRandom_generatingIntegerBounded_withThreadLocalRandom() throws Exception {
int min = 1;
int max = 10;
int threadIntBound = ThreadLocalRandom.current().nextInt(min, max);
System.out.println(threadIntBound);
}
</code></pre>
<blockquote>
<p>包含 1 而不包含 10</p>
</blockquote>
<hr/>
<h2 id="toc_6">随机数 Long 的生成</h2>
<h3 id="toc_7">生成无边界的 Long</h3>
@Test
public void testRandom_generatingLongUnbounded() throws Exception {
long unboundedLong = new Random().nextLong();
System.out.println(unboundedLong);
}
</code></pre>
<blockquote>
<p>因为 Random 类使用的种子是 48bits,所以 nextLong 不能返回所有可能的 long 值,long 是 64bits。</p>
</blockquote>
<h3 id="toc_8">生成有边界的 Long</h3>
@Test
public void testRandom_generatingLongBounded_withRange() throws Exception {
long min = 1;
long max = 10;
long rangeLong = min + (((long) (new Random().nextDouble() * (max - min))));
System.out.println(rangeLong);
}
</code></pre>
<blockquote>
<p>以上只会生成 1 到 10 的 long 类型的随机数</p>
</blockquote>
<h3 id="toc_9">使用 Apache Commons Math 来生成有边界的 Long</h3>
@Test
public void testRandom_generatingLongBounded_withApacheMath() throws Exception {
long min = 1;
long max = 10;
long rangeLong = new RandomDataGenerator().nextLong(min, max);
System.out.println(rangeLong);
}
</code></pre>
<blockquote>
<p>此方式主要使用的<a href="http://commons.apache.org/proper/commons-math/javadocs/api-3.6/org/apache/commons/math3/random/RandomDataGenerator.html">RandomDataGenerator</a>类提供的生成随机数的方法</p>
</blockquote>
<h3 id="toc_10">使用 Apache Commons Lang 的工具类来生成有边界的 Long</h3>
@Test
public void testRandom_generatingLongBounded_withApacheLangInclusive() throws Exception {
long min = 1;
long max = 10;
long longBounded = RandomUtils.nextLong(min, max);
System.out.println(longBounded);
}
</code></pre>
<blockquote>
<p><a href="https://commons.apache.org/proper/commons-lang/javadocs/api-3.3/org/apache/commons/lang3/RandomUtils.html">RandomUtils</a>提供了对 java.util.Random 的补充</p>
</blockquote>
<h3 id="toc_11">使用 ThreadLocalRandom 生成有边界的 Long</h3>
@Test
public void testRandom_generatingLongBounded_withThreadLocalRandom() throws Exception {
long min = 1;
long max = 10;
long threadLongBound = ThreadLocalRandom.current().nextLong(min, max);
System.out.println(threadLongBound);
}
</code></pre>
<hr/>
<h2 id="toc_12">随机数 Float 的生成</h2>
<h3 id="toc_13">生成 0.0-1.0 之间的 Float 随机数</h3>
@Test
public void testRandom_generatingFloat0To1() throws Exception {
float floatUnbounded = new Random().nextFloat();
System.out.println(floatUnbounded);
}
</code></pre>
<blockquote>
<p>以上只会生成包含 0.0 而不包括 1.0 的 float 类型随机数</p>
</blockquote>
<h3 id="toc_14">生成有边界的 Float 随机数</h3>
@Test
public void testRandom_generatingFloatBounded_withRange() throws Exception {
float min = 1f;
float max = 10f;
float floatBounded = min + new Random().nextFloat() * (max - min);
System.out.println(floatBounded);
}
</code></pre>
<h3 id="toc_15">使用 Apache Common Math 来生成有边界的 Float 随机数</h3>
@Test
public void testRandom_generatingFloatBounded_withApacheMath() throws Exception {
float min = 1f;
float max = 10f;
float randomFloat = new RandomDataGenerator().getRandomGenerator().nextFloat();
float generatedFloat = min + randomFloat * (max - min);
System.out.println(generatedFloat);
}
</code></pre>
<h3 id="toc_16">使用 Apache Common Lang 来生成有边界的 Float 随机数</h3>
@Test
public void testRandom_generatingFloatBounded_withApacheLang() throws Exception {
float min = 1f;
float max = 10f;
float generatedFloat = RandomUtils.nextFloat(min, max);
System.out.println(generatedFloat);
}
</code></pre>
<h3 id="toc_17">使用 ThreadLocalRandom 生成有边界的 Float 随机数</h3>
<blockquote>
<p>ThreadLocalRandom 类没有提供</p>
</blockquote>
<hr/>
<h2 id="toc_18">随机数 Double 的生成</h2>
<h3 id="toc_19">生成 0.0d-1.0d 之间的 Double 随机数</h3>
@Test
public void testRandom_generatingDouble0To1() throws Exception {
double generatorDouble = new Random().nextDouble();
System.out.println(generatorDouble);
}
</code></pre>
<blockquote>
<p>与 Float 相同,以上方法只会生成包含 0.0d 而不包含 1.0d 的随机数</p>
</blockquote>
<h3 id="toc_20">生成带有边界的 Double 随机数</h3>
@Test
public void testRandom_generatingDoubleBounded_withRange() throws Exception {
double min = 1.0;
double max = 10.0;
double boundedDouble = min + new Random().nextDouble() * (max - min);
System.out.println(boundedDouble);
assertThat(boundedDouble, greaterThan(min));
assertThat(boundedDouble, lessThan(max));
}
</code></pre>
<h3 id="toc_21">使用 Apache Common Math 来生成有边界的 Double 随机数</h3>
@Test
public void testRandom_generatingDoubleBounded_withApacheMath() throws Exception {
double min = 1.0;
double max = 10.0;
double boundedDouble = new RandomDataGenerator().getRandomGenerator().nextDouble();
double generatorDouble = min + boundedDouble * (max - min);
System.out.println(generatorDouble);
assertThat(generatorDouble, greaterThan(min));
assertThat(generatorDouble, lessThan(max));
}
</code></pre>
<h3 id="toc_22">使用 Apache Common Lang 生成有边界的 Double 随机数</h3>
@Test
public void testRandom_generatingDoubleBounded_withApacheLang() throws Exception {
double min = 1.0;
double max = 10.0;
double generatedDouble = RandomUtils.nextDouble(min, max);
System.out.println(generatedDouble);
}
</code></pre>
<h3 id="toc_23">使用 ThreadLocalRandom 生成有边界的 Double 随机数</h3>
@Test
public void testRandom_generatingDoubleBounded_withThreadLocalRandom() throws Exception {
double min = 1.0;
double max = 10.0;
double generatedDouble = ThreadLocalRandom.current().nextDouble(min, max);
System.out.println(generatedDouble);
}
</code></pre>
<h2 id="toc_24">JAVA 中有多少可以实现随机数的类或方法?</h2>
<ul>
<li>java.util.Random 这个类提供了生成 Bytes、Int、Long、Float、Double、Boolean 的随机数的方法</li>
<li>java.util.Math.random 方法提供了生成 Double 随机数的方法,这个方法的内部实现也是调用了 java.util.Random 的 nextDouble 方法,只不过它对多线程进行了更好的支持,在多个线程并发时会减少每个随机数生成器的竞争</li>
<li>第三方工具类,如 Apache Common Lang 库与 Apache Common Math 库中提供的随机数生成类,真正使用一行代码来实现复杂的随机数生成</li>
<li>java.util.concurrent.ThreadLocalRandom 专为多线程并发使用的随机数生成器,使用的方法为 ThreadLocalRandom.current.nextInt(),此类是在 JDK1.7 中提供的,并且特别适合 ForkJoinTask 框架,而且在这个类中直接提供了生成有边界的随机数的操作,如<code>public int nextInt(int origin, int bound)</code>,这样也可以一行代码来实现复杂的随机数生成了。</li>
</ul>
<blockquote>
<p>最后的总结为单线程中使用 java.util.Random 类,在多线程中使用 java.util.concurrent.ThreadLocalRandom 类。</p>
</blockquote>
<h2 id="toc_25">总结</h2>
<p>JAVA 在不 JDK 升级中不断在完善 API,现在可以使用 JDK 原生的 API 写出优雅的代码了。所有的这些测试完整的代码在<a href="https://github.com/peng051410/gotoBase/blob/master/coreJava/src/test/java/com/tomyli/java8/JavaRandomTest.java">这里</a></p>
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于