在Java 8中,一个并行流是否可能给出与串行流不同的结果? 根据我的信息,一个并行流和串行流是一样的,只不过被分成了多个子流。这是关于速度的问题。对所有元素的操作都完成后,在最后合并子流的结果。最终,我认为并行流和串行流的操作结果应该是相同的。所以我的问题是,这段代码是否可能给出不同的结果?如果有可能,为什么会发生?
int[] i = {1, 2, 5, 10, 9, 7, 25, 24, 26, 34, 21, 23, 23, 25, 27, 852, 654, 25, 58};
Double serial = Arrays.stream(i).filter(si -> {
return si > 5;
}).mapToDouble(Double::new).map(NewClass::add).reduce(Math::atan2).getAsDouble();
Double parallel = Arrays.stream(i).filter(si -> {
return si > 5;
}).parallel().mapToDouble(Double::new).map(NewClass::add).reduce(Math::atan2).getAsDouble();
System.out.println("serial: " + serial);
System.out.println("parallel: " + parallel);
public static double add(double i) {
return i + 0.005;
}
结果如下:
serial: 3.6971567726175894E-23
parallel: 0.779264049587662
atan2
进行缩减完全没有意义。例如,它不是可结合的。 - Paul Boddingtonsi -> { return si > 5; }
应该改为si -> si > 5
,并且您需要在parallel()
之后进行过滤。 - Andreas.parallel()
方法,结果是相同的。 - Tagir Valeev.mapToDouble(Double::new)
将每个int
扩展为double
,将它们装箱成Double
对象,然后再将它们拆箱为double
值。如果要将int
转换为double
,则.mapToDouble(i->i)
会更直接,跳过对象创建。但是更简单的方法是.asDoubleStream()
... 如果您真的需要装箱的值,请使用Double::valueOf
而不是Double::new
。 - Holger