java—为什么数据没有添加到Map中,而相同的函数可以用于将数据集打印到控制台我做错什么了?

taor4pac  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(290)
dataset = dataset.withColumn("Probability", callUDF("checkProb", col("Confirmed"), col("Population")));

Map<String, Double> probability= new HashMap<>();
ArrayList<String> a =new ArrayList<>();
dataset= dataset.limit(35);
dataset.show(36);
dataset.foreach((ForeachFunction<Row>) row -> a.add(row.getAs("State").toString()));

System.out.println(a.size());

不管我做什么尺寸都是0。我尝试了arraylist和map,但都不起作用。

moiiocjp

moiiocjp1#

spark将工作负载分配给不同的执行者。驱动程序进程为每个执行器提供每个局部变量的副本。此副本独立于原始变量,如果执行者更改副本,则原始变量保持不变。 foreach 由执行者运行,每个执行者都有自己的 a . 如果您打印 ArrayList :

ArrayList<String> a = new ArrayList<>();
dataset = dataset.limit(35);
dataset.show(36);
System.out.println("a in the driver process: " + System.identityHashCode(a));
dataset.foreach((ForeachFunction<Row>) row -> {
    a.add(row.getAs("value").toString());
    System.out.println("a on an executor " + System.identityHashCode(a));
});
System.out.println("back in the driver process: " + System.identityHashCode(a));

印刷品

a in the driver process: 1859780907
a on an executor 229101481
a on an executor 2105534525
a on an executor 1982276971
back in the driver process: 1859780907

因此 ArrayList 你的电话 size() 永远不会改变。
顺便说一句:在执行器上使用驱动程序的局部变量是一种不好的做法,因为这可能会导致(不仅仅是性能)问题。您应该考虑使用广播变量和累加器。

相关问题