我有这样的案例类:


 案例类Ais(NotImportant)
扩展Serializable {


 var flag = Ais.Flag.NotFlagged
 var cluster = Ais.Unknown
 var visited = false

 override def toString():String = {
的 “$集群,$标记,$走访” 
 }
}



 运行我的算法后,我最终得到两个类型为的数据集(Int,Ais) )
其中 Ais
对象中的变量包含信息。我需要结合它们。对我来说最重要的是 var cluster
和 var visited
的值。然而在 union
之后,它们被重置为默认值。
labeledInner.foreach(println(_))//这很好&# xA; println(“==========”)
 labeledOuter.foreach(println(_))//这也很好
 println(“======== ==“)
 labeledOuter.union(labeledInner).foreach(println(_))// Here
 //一切都设置为默认



 我正在运行Spark 2.1和Scala 2.11.8。

答案 0 :(得分:4)
在使用Spark时,你不应该在case类中使用mutable vars
- 这些不能“存活”Spark的编码,所以任何非常重要的数据集使用(比如使用{{触发编码和解码的1}})不会保留这些字段。
<强>为什么强>? Spark内置了编码器,可以有效地将对象编码为字节数组(以及后面的数组)。对于案例类(实际上,对于所有union
,主要是案例类和元组),编码器只编码案例类字段,它们被定义为类参数(在您的情况下) , 只有1个}})。您可以通过为案例类创建相关编码器并检查其架构:
Product
如您所见 - 只有NotImportant
幸存,case class A(s: String) {
var a: Int = 0
}
Encoders.product[A].schema.printTreeString()
// root
// |-- s: string (nullable = true)
不属于架构。
有什么选择?使用Spark(实际上是Scala)时,你应该避免使用 mutable 字段。尝试对数据建模以将所有字段包含为不可变字段,例如:
s
然后,为了“改变”这些对象,您可以使用创建新实例的a
方法,其中一些(或没有)字段已更改,例如:
case class Ais(flag: Flag, cluster: Cluster, visited: Boolean)
这些对象可以安全地与Spark一起使用(它们“存活”序列化并且是不可变的。)