Java 8里面的java.util.Random

本文介绍了Java8中java.util.Random类新增的功能,即能够生成随机数流,并展示了如何使用这些流生成伪随机数和高斯随机数。此外,还通过实例演示了如何利用流API分析上百万个随机数的分布情况。
在Java 8里面,java.util.Random经过改进后增加了一个实用的功能,可以返回一个随机数的流。

比如,如果要生成[0, 1)之间的随机浮点数的无限流:

Random random = new Random();
DoubleStream doubleStream = random.doubles();


或者要生成[0, 100)间的整数的无限流:
Random random = new Random();
IntStream intStream = random.ints(0, 100);


那么一个无限的随机流有什么用呢?下面我会列举出几个场景。不过需要注意的是这是个无限流,一旦开始操作这个流,就必须在有限的操作内终止,否则这个操作将永远不会停止!

比如,获取10个随机整数并打印出来:
intStream.limit(10).forEach(System.out::println);

或者生成一个包含100个随机整数的列表:
List<Integer> randomBetween0And99 = intStream
.limit(100)
.boxed()
.collect(Collectors.toList());


对于高斯伪随机数来说,没有像random.doubles()这样创建流的方式,但是用Java 8提供的一个方法也很容易实现:

Random random = new Random();
DoubleStream gaussianStream = Stream.generate(random::nextGaussian).mapToDouble(e -> e);


这里我用了Stream.generate这个API来调用了一个高斯数的生产者,这个生产者用的是Random类里的一个现成的方法。

现在,有了伪随机的浮点数和高斯浮点数后,我们来做点有意思的事情吧。我想做的是获取这两个流生成的浮点数的一个分布情况,正常情况下,伪随机浮点数应该是呈连续均匀分布的,而高斯浮点数应该呈正态分布。

在下面的代码中,我将会生成一份上百万随机数的分布状况,这里用到了Java8的流API中提供的大量设施:

Random random = new Random();
DoubleStream doubleStream = random.doubles(-1.0, 1.0);
LinkedHashMap<Range, Integer> rangeCountMap = doubleStream.limit(1000000)
.boxed()
.map(Ranges::of)
.collect(Ranges::emptyRangeCountMap, (m, e) -> m.put(e, m.get(e) + 1), Ranges::mergeRangeCountMaps);

rangeCountMap.forEach((k, v) -> System.out.println(k.from() + "\t" + v));


上面的代码输出如下:

-1  49730
-0.9 49931
-0.8 50057
-0.7 50060
-0.6 49963
-0.5 50159
-0.4 49921
-0.3 49962
-0.2 50231
-0.1 49658
0 50177
0.1 49861
0.2 49947
0.3 50157
0.4 50414
0.5 50006
0.6 50038
0.7 49962
0.8 50071
0.9 49695



同样再生成一个高斯随机数的分布:
Random random = new Random();
DoubleStream gaussianStream = Stream.generate(random::nextGaussian).mapToDouble(e -> e);
LinkedHashMap<Range, Integer> gaussianRangeCountMap =
gaussianStream
.filter(e -> (e >= -1.0 && e < 1.0))
.limit(1000000)
.boxed()
.map(Ranges::of)
.collect(Ranges::emptyRangeCountMap, (m, e) -> m.put(e, m.get(e) + 1), Ranges::mergeRangeCountMaps);

gaussianRangeCountMap.forEach((k, v) -> System.out.println(k.from() + "\t" + v));


数据分布图不出所料:
随机数的:
[img]http://www.javacodegeeks.com/wp-content/uploads/2014/01/pseudorandom.png[/img]

高斯随机数的:
[img]http://www.javacodegeeks.com/wp-content/uploads/2014/01/gaussian.png[/img]


更多文章请关注: [url=http://it.deepinmind.com]deepinmind[/url]
<think>我们正在讨论Java编程语言中的import语句,特别是`import java.util.Random`。根据用户的需求,我们需要解释这个语句的含义。 首先,`import`语句在Java中用于引入其他包中的类或接口,以便在当前源文件中使用它们,而无需使用完全限定名(即包名+类名)。 其次,`java.util.Random`是Java标准库中的一个类,用于生成伪随机数。 因此,`import java.util.Random;`语句的意思是:导入`java.util`包中的`Random`类,使得在当前源文件中可以直接使用`Random`类,而不必每次都写全路径`java.util.Random`。 例如,如果没有导入,我们需要这样创建Random对象: java.util.Random rand = new java.util.Random(); 而导入后,就可以简写为: Random rand = new Random(); 此外,还可以使用通配符导入整个包,例如`import java.util.*;`,但是通常建议使用具体导入(即导入具体的类),以避免命名冲突和减少编译时间。 注意:在同一个包中的类不需要导入,Java默认会导入`java.lang`包(例如String、System等类),所以不需要显式导入。 根据引用[2]中提到的使用Random的例子,我们可以知道,创建Random对象后,通常使用其方法来获取随机数,如`nextInt()`。 因此,我们可以给出一个简单的示例代码: ```java import java.util.Random; // 导入Random类 public class Example { public static void main(String[] args) { Random random = new Random(); // 创建Random对象 int randomNumber = random.nextInt(100); // 生成0到99之间的随机整数 System.out.println("随机数: " + randomNumber); } } ``` 在这个例子中,我们首先导入Random类,然后在main方法中创建了一个Random对象,并调用其`nextInt(100)`方法生成一个0到99的随机整数。 总结:`import java.util.Random;`的作用是引入`java.util.Random`类,简化代码书写。 根据要求,我们需要生成相关问题: §§相关问题§§ 1. Java中的import语句还有哪些使用方式? 2. 除了Random类,java.util包中还有哪些常用的类? 3. 如果不使用import语句,如何在代码中使用其他包中的类? 4. 使用通配符导入整个包(如import java.util.*;)有什么优缺点? </think>### `import java.util.Random` 语句的含义解释 在 Java 中,`import java.util.Random` 是一个**包导入声明**,其核心含义是: **将 `java.util` 包中的 `Random` 类引入当前代码文件的作用域,使开发者能直接使用 `Random` 类而无需书写完整路径。** 具体解析如下: 1. **`java.util` 包** 这是 Java 标准库中提供实用工具类的核心包,包含集合框架、日期时间工具、随机数生成器等常用工具(如引用[3]提到的 `Map` 集合也在此包中)。 2. **`Random` 类** 专门用于生成**伪随机数序列**的类(如引用[2]中尝试生成随机数的场景)。提供以下常用方法: - `nextInt()`:生成随机整数 - `nextInt(int bound)`:生成范围在 `[0, bound)` 的随机整数(如 `nextInt(100)` 生成 0-99 的随机数) - `nextDouble()`:生成 [0.0, 1.0) 的随机浮点数 3. **导入前后的代码对比** - ❌ 未导入时需要完整路径: ```java java.util.Random rand = new java.util.Random(); ``` - ✅ 导入后可直接使用类名: ```java Random rand = new Random(); int num = rand.nextInt(100); // 生成0-99的随机整数 ``` 4. **深层作用** - **减少代码冗余**:避免重复书写长包路径 - **提高可读性**:简化代码逻辑 - **编译优化**:编译器自动定位类文件位置(实际类文件路径为 `java/util/Random.class`) > ⚠️ 注意:一个文件可包含多个 `import` 语句(如同时导入 `Random` 和引用[3]中的 `Map` 类),也可用通配符 `import java.util.*;` 导入整个包(但可能增加命名冲突风险)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值