Java 流式编程概述
让我们首先从随机数说起。
1 随机数
真正的随机数是使用物理现象产生的,比如投掷钱币。这种随机数发生器叫做物理性随机数发生器。
它的缺点是技术要求比较高。
这幅图是芬兰的钱币。
但这种通过物理性随机数发生器生成的真随机数,才是真正的随机,体现的是绝对的公平。
伪随机数是有规律的,只不过这个规律周期比较长,但还是可以预测的。主要原因是伪随机数是计算机使用算法模拟出来的,因为这个过程并不涉及到物理过程,所以自然不可能具有真随机数的特性。
目前用的比较广泛的有以下两种算法:
- 线性同余算法周期:2^32= 4294967296 ≈42亿
- 梅森旋转算法( Mersenne twister )周期: 2^19937−1=Infinity
梅森旋转算法,也是目前使用最多的伪随机数生成算法,它是由两位日本的数学家松本真和西村拓士在1997年提出的。
撒哈拉沙漠中的沙子数量级是 10^26;宇宙中目前可观察的粒子数量级是 10^87。而梅森旋转算法的周期数量级比宇宙中目前可观察的粒子还高出数千个数量级。
图片是日本数学家小平邦彦(1915年3月16日-1997年7月26日)。他以在代数几何和紧复解析曲面理论方面的出色工作而出名。
伪随机数特性就是:只要给定了种子,那么得到的随机数序列就是相同的。
2 比较命令式编程与流式编程
Bruce Eckel 举了这样一个示例:随机输出 5 至 20 之间不重复的整数并进行排序。
如果使用命令式编程方式,应该是这样的:
Random rand = new Random(47);
SortedSet<Integer> ints = new TreeSet<>();
while (ints.size() < 7) {
int r = rand.nextInt(20);
if (r < 5) {//丢弃 5 之前的数字
continue;
}
ints.add(r);
}
System.out.println(ints);
运行结果:
[7, 8, 9, 11, 13, 15, 18]
- 首先,我们给 Random 对象一个种子,以便程序再次运行时产生相同的随机数序列。
- 程序一共定义了 3 个变量:rand、ints 与 r。
- 并且显式地编写迭代机制,即外部迭代。
- 还通过 if 语句,过滤小于 5 的结果值。
如果采用流式编程方式,那么代码是这样的:
new Random(47).ints(5, 20)
.distinct().limit(7).sorted().forEach(System.out::println);
运行结果:
6
10
13
16
17
18
19
- 无须定义变量。流可以在不使用赋值或变量的情况下对有状态的系统进行建模。
- 流式编程采用内部迭代,比如示例代码中的 forEach 方法。
- 流的编程方式使得程序更加简洁并且更易于理解,比如无须 if 语句过滤小于 5 的结果值。
总的来说,流式编程是一种声明式编程(Declarative programming),即声明要做什么,而非怎么做的编程风格。
3 为什么叫流式编程
因为编程方式与数据流转方式,好像往杯子里倒水,水不断地从高处往下流入杯中。因此,就形象地称其为“流式编程”。
上一篇: CSS第一天笔记
下一篇: Java网络编程概述