2016-06-09 99 views
0

我是新的斯卡拉,顯然不明白爲什麼這段代碼不起作用。斯卡拉。映射後的空變量

我從第一數據幀創建陣列,並創建第二陣列時開始檢查在兩個陣列相同的數據。 在相同數據的情況下 - 實現可變文本

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 

爲什麼當我打印文本映射的變量正在實施一段時間,但是當我地圖後,再打印出來 - 好像它從來沒有在地圖?

__

,當我想用​​ListBuffer[String]()做到這一點給了我同樣的效果。

我試圖用這個代碼做的事情 - 從卡桑德拉 __ 發現在不同的表相同的數據不知道是什麼的答案是更好> <都可以接受我的問題=)

回答

1

功能你寫的rdd.map在後端做了很多事情。你看到這種行爲的原因是因爲你的主代碼和rdd.map函數在不同的線程中工作。只有在並行上下文情況下,變量才能通過並返回。

嘗試使用這樣的一個accumulator。這就是爲什麼從不建議使用可變變量的原因。它會讓你困惑不已,因爲它們是不可變的。

+0

謝謝!我認爲我需要閱讀一些關於Scala \ Spark組合的書籍=) – ANTVirGEO

+0

作爲學習使用不可序列化的類的嘗試的一種方法(與String不同)。你會得到一個對象不可序列化的異常。代碼運行期間發生的情況如下:您在並行上下文中引用來自本地上下文的變量。該變量被序列化,並通過網絡(如果任務在不同的機器上運行,則通過網絡)傳遞給映射器。 – Sohaib

1

這不是Scala中,這是一個問題星火明確。不能使用可變的變量是這樣,因爲在傳遞給map匿名函數的代碼是要在其他計算機上執行(這是用放電的點!),並會改變自己的副本text,而不是一個在司機。

它詳細http://spark.apache.org/docs/latest/programming-guide.html#understanding-closures-a-nameclosureslinka有一個非常類似的例子來說明。

+0

非常感謝,沒有捕捉到我腦海中的所有圖片 – ANTVirGEO