斯卡拉。映射

时间:2016-06-09 08:56:34

标签: scala dataframe spark-dataframe

我是Scala的新手,显然不明白为什么这段代码不起作用。

我从第一个DataFrame创建数组,并在创建第二个数组时开始检查两个数组中的相同数据。 如果数据相同 - 实现变量文本

var text = "Hello!"
val dfOriginDate = sqlContext.sql("SELECT name, age FROM table2")
val arrOriginDate = dfOriginDate.rdd.map(r => {
     r(0).toString + r(1).toString
   }).collect()

val dfNewDate = sqlContext.sql("SELECT name, age FROM table")
dfNewDate.rdd.map(r => {
  if (arrOriginDate contains(r(0).toString + r(1).toString)) {
    text += "found some stupid things"
    print(text + " for the first time\r\n")
  }
}).collect()

println(text + " for the second time")

在输出时我有这个:

Hello! found some stupid things for the first time
Hello! for the second time

为什么当我正在实现映射变量时打印文本,但是当我在Map之后再次打印它时 - 看起来它似乎从未出现在Map中?

__

当我尝试用ListBuffer[String]()做这件事时,它给了我同样的效果。

我正在尝试使用此代码 - 在Cassandra的不同表中查找相同的数据 __ 不知道答案更好><两者都可以接受我的问题=)

2 个答案:

答案 0 :(得分:1)

你写的函数rdd.map在后端做了很多事情。您看到此行为的原因是因为您的主代码和rdd.map函数在不同的线程中工作。在并行上下文的情况下,变量无法通过和返回。

尝试使用accumulator进行此操作。这就是为什么永远不建议使用可变变量。它会让你感到困惑,因为如果它们不可变,你就不应该被困住。

答案 1 :(得分:1)

这不是关于Scala,具体是Spark问题。你不能使用像这样的可变变量,因为传递给map的匿名函数中的代码将在其他机器上执行(这就是使用Spark!)并将改变他们的 text的副本,而不是驱动程序中的副本。

详细解释了http://spark.apache.org/docs/latest/programming-guide.html#understanding-closures-a-nameclosureslinka的一个非常相似的例子。