java高*之并行流的缩减操作
直接看代码,解释在代码注释中。
package java8.lambda;
import java.util.ArrayList;
import java.util.List;
/**
* @author chuer
* @Description: 注意java的版本必须是8
* @date 2015年4月20日 下午4:37:05
* @version V1.0
*/
public class ReduceTest {
/**
* 我们要计算列表中数值的平方根的和
* @param args
*/
public static void main(String[] args) {
//初始化列表
List<Double> numList = new ArrayList<>();
for(double i = 1.0;i<100.0;i++){
numList.add(i);
}
//串行普通版本
//先计算出每个数的平方根,生成一个新流,然后使用聚合函数sum计算结果
double sum = numList.stream().mapToDouble(num ->{return Math.sqrt(num);}).sum();
System.out.println("串行普通版本: "+sum);
//串行reduce版本
//我们给定一个初始值0.0,也就是初试结果,然后用结果加上下一个数的平方根,串行执行。
Double reduce1 = numList.stream().reduce(0.0, (num1,num2)->{
return num1 + Math.sqrt(num2);
});
System.out.println("串行reduce版本: "+reduce1);
//并行错误的reduce版本
//注意这里我们使用并行流,其实我们可以把它想成多个串行流同时执行,这多个串行流分别执行列表的不同部分,每个
//串行流的初始值都是0.0,而且每个串行流都会产生一个结果,怎么组织这些结果呢?我们这里并没有告诉程序如何组织
//结果,程序默认使用我们给出的lambda表达式进行组织,也就是使用第一个结果加上第二个结果的平方根,所以结果
//跟定是错误的。
Double reduce2 = numList.stream().parallel().reduce(0.0, (num1,num2)->{
return num1 + Math.sqrt(num2);
});
System.out.println("并行错误的reduce版本: "+reduce2);
//并行的reduce版本
//这次的代码我们给出了组织结果的方式,也就是num1+num2,也就是平方根之和。所以结果是正确的
Double reduce3 = numList.stream().parallel().reduce(0.0, (num1,num2)->{
return num1 + Math.sqrt(num2);
}, (num1,num2)->{
return num1 + num2;
});
System.out.println("并行的reduce版本: "+reduce3);
}
}
结果如下:
串行普通版本: 661.4629471031477
串行reduce版本: 661.4629471031477
并行错误的reduce版本: 99.83376107055487
并行的reduce版本: 661.4629471031478