如何从另一个中减去RDD [(Key,Object)]?

时间:2015-04-27 16:55:25

标签: scala apache-spark rdd

我想更改数据的格式,从RDD(Label:String,(ID:String,Data:Array [Double]))到RDD对象,标签,id和数据作为组件。 但是当我连续两次打印RDD时,对象的引用会改变:

class Data_Object(private val id:String, private var vector:Vector) extends Serializable {
var label = ""
...
}

First print 
(1,ms3.Data_Object@35062c11)
(2,ms3.Data_Object@25789aa9)

Second print
(2,ms3.Data_Object@6bf5d886)
(1,ms3.Data_Object@a4eb65)

我认为这解释了为什么subtract方法不起作用。那么我可以将subtract与对象一起用作值,还是返回到我的经典模型?

1 个答案:

答案 0 :(得分:2)

除非另行指定,否则使用引用相等性(即它们的内存地址)比较Scala(和Java)中的对象。它们也会根据此地址打印出来,因此Data_Object@6bf5d886等等。

使用引用相等意味着具有相同属性的两个Data_Object实例将不会比较为相等,除非它们是完全相同的对象。此外,他们的引用将从一次运行更改为下一次运行。

特别是在像Spark这样的分布式系统中,这并不好 - 我们需要能够根据它们的属性判断两个不同 JVM中的两个对象是否相同。在此问题得到解决之前,像subtract这样的RDD操作将无法提供您期望的结果。

幸运的是,这通常很容易在Scala / Spark中修复 - 将您的类定义为case class。这会自动生成从类的所有属性派生的equalshashcodetoString方法。例如:

case class Data_Object(id:String, label:String, vector:Vector)

如果您只想根据属性部分比较对象,则必须定义自己的equalshashcode方法。例如,请参阅Programming in Scala