我想更改数据的格式,从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
与对象一起用作值,还是返回到我的经典模型?
答案 0 :(得分:2)
除非另行指定,否则使用引用相等性(即它们的内存地址)比较Scala(和Java)中的对象。它们也会根据此地址打印出来,因此Data_Object@6bf5d886
等等。
使用引用相等意味着具有相同属性的两个Data_Object
实例将不会比较为相等,除非它们是完全相同的对象。此外,他们的引用将从一次运行更改为下一次运行。
特别是在像Spark这样的分布式系统中,这并不好 - 我们需要能够根据它们的属性判断两个不同 JVM中的两个对象是否相同。在此问题得到解决之前,像subtract
这样的RDD操作将无法提供您期望的结果。
幸运的是,这通常很容易在Scala / Spark中修复 - 将您的类定义为case class。这会自动生成从类的所有属性派生的equals
和hashcode
和toString
方法。例如:
case class Data_Object(id:String, label:String, vector:Vector)
如果您只想根据属性部分比较对象,则必须定义自己的equals
和hashcode
方法。例如,请参阅Programming in Scala。