JAVA SE 8 的流库-1.12约简操作

1.12约简操作

reduce方法是一种用于从流中计算某个值得通用机制。
例:接受一个二元函数,并从前两个元素开始持续应用它。

List<Integer>values = Arrays.asList(0,1,2,3,4,5,6,7,8,9);
Optional <Integer> sum = values.stream().reduce((x,y)->x+y);//result = 45

在上面的情况中reduce方法会计算v0+v1+v2+…,其中vi是流中元素。如果流为空则返回一个Optional.empty。

通常,如果reduce方法有一项约简操作op,那么该约简就会产生v0 op v1 op v2 op…,这项操作应该是可结合的((x op y)op z = x op (y op z)):机组和元素使使用的顺序不应该成为问题。这在使用并行流时,可以执行高效的约简。

注意:减法是一个不可结合操作的例子。==减法可用reduce,但是不能并行操作(parallelStream)。上述代码,stream结果为-45,parallelStream结果为5(出错)。

通常会有一个幺元值e使得 e op x = x,可以使用这个元素作为计算的起点。
例如:0是加法的幺元,如果流为空,则返回幺元值,也就不需要处理Optional类了。

List<Integer>values = Arrays.asList();
Integer sum = values.stream().reduce(0,(x,y)->x-y);//注意返回值为Integer, 而非Optional

如果想要对对象流的某些属性求和(例如求字符串流中所有字符串的长度),那么就不能使用简单形式的reduce,而是需要(T,T)->T这样的函数,==即引元和结果类型相同的函数。==但是在这种情况下,流的元素具有String类型,而累计结果是整数。

首先,需要提供一种“累积器”函数(total,word)-> total + word.length()。这个函数会被反复调用,产生累积的总和。
但是,当计算被并行化时,会有多个这种类型的计算,需要将他们的结果合并。因此需要第二个函数来执行此处理。

words = Stream.of(contents.split(" "));
int result = words.reduce(0,
				(total, word)->total+word.length(),//引元和结果类型相同的函数
				(total1,total2)->total1+total2);
				//这里有一个小疑问:为什么total是int类型,而word是String类型

注意:通常,映射为数字流并使用其方法来计算总和、最大值和最小值会更容易。

如有问题,请评论处指正,Thanks♪(・ω・)ノ

猜你喜欢

转载自blog.csdn.net/z036548/article/details/84197437