var RetainKeyList: mutable.Seq[String] = new scala.collection.mutable.ListBuffer[String]()
for(element<-ts_rdd)
{
var elem1 = element._1
var kpssSignificance: Double = 0.05
var dOpt: Option[Int] = (0 to 2).find
{
diff =>
var testTs = differencesOfOrderD(element._2, diff)
var (stat, criticalValues) = kpsstest(testTs, "c")
stat < criticalValues(kpssSignificance)
}
var d = dOpt match
{
case Some(v) => v
case None => 300000
}
if(d.equals(300000))
{
println("Bad Key: " + elem1)
RetainKeyList += elem1
}
大家好,
我创建了一个空的可变列表缓冲区var RetainKeyList: mutable.Seq[String] = new scala.collection.mutable.ListBuffer[String]()
,并尝试在 for 循环中向其中添加字符串 elem1 。
当我尝试编译代码时,它挂起,没有错误消息,但是如果我删除代码RetainKeyList += elem1
,则可以正确打印所有 elem1 字符串。
我在这里做错了什么?有没有一种更干净的方法来收集在for循环中生成的所有字符串 elem1 ?
答案 0 :(得分:0)
长话短说,您的代码在分布式环境中运行,因此不会修改本地集合。每个星期都会有人问这个问题,如果您不了解分布式计算的含义,请不要使用像Spark这样的分布式框架。
此外,您还在各处滥用可变性。而且可变性和分布式环境不能很好地发挥作用。
无论如何,这是解决问题的一种更好的方法。
val retainKeysRdd = ts_rdd.map {
case (elem1, elem2) =>
val kpssSignificance = 0.05d
val dOpt = (0 to 2).find { diff =>
val testTs = differencesOfOrderD(elem2, diff)
val (stat, criticalValues) = kpsstest(testTs, "c")
stat < criticalValues(kpssSignificance)
}
(elem1 -> dOpt)
} collect {
case (key, None) => key
}
这将返回带有保留键的 RDD 。如果您确实确定需要将此作为本地集合,并且它们不会消耗您的内存,则可以执行以下操作:
val retainKeysList = retainKeysRdd.collect().toList