我有这样的事情:
object MyObject {
var element1 /**/
var element2 /**/
var myOtherObject: OtherObject = new OtherObject
}
object MyOtherObject {
var something1 /**/
var something2 /**/
var myList: List[T] = List()
}
def myUpdateFunction(iMyObject: MyObject) : SomeObject = {
var myCopiedObject = iMyObject
myCopiedObject.myList.dropRight
/*checkpoint*/
val myAwesomeOtherObject = new MyOtherObject
/*perform multiple tasks to update myAwesomeOtherObject members*/
myAwesomeOtherObject
}
当我在"检查点"上检查myUpdateFunction
执行时注释,我观察我的myCopiedObject.myList
已成功转换,但我的iMyObject
也有,即。 iMyObject.myList
被一个人截断了。
我不明白这是怎么发生的。
任何线索,任何人?
顺便说一下,我正在使用spark
答案 0 :(得分:2)
之所以发生这种情况,是因为您只是将同一个对象分配给另一个引用。 Exception in thread "main" java.io.IOException: mkdir of C:/Users/Manuel%20Mourato/AppData/Local/Temp/temporary-891579db-0442-4e1c-8642-d41c7885ab26/offsets failed
at org.apache.hadoop.fs.FileSystem.primitiveMkdir(FileSystem.java:1065)
at org.apache.hadoop.fs.DelegateToFileSystem.mkdir(DelegateToFileSystem.java:176)
at org.apache.hadoop.fs.FilterFs.mkdir(FilterFs.java:197)
at org.apache.hadoop.fs.FileContext$4.next(FileContext.java:730)
at org.apache.hadoop.fs.FileContext$4.next(FileContext.java:726)
at org.apache.hadoop.fs.FSLinkResolver.resolve(FSLinkResolver.java:90)
at org.apache.hadoop.fs.FileContext.mkdir(FileContext.java:733)
at org.apache.spark.sql.execution.streaming.HDFSMetadataLog$FileContextManager.mkdirs(HDFSMetadataLog.scala:281)
at org.apache.spark.sql.execution.streaming.HDFSMetadataLog.<init>(HDFSMetadataLog.scala:57)
at org.apache.spark.sql.execution.streaming.StreamExecution.<init>(StreamExecution.scala:131)
at org.apache.spark.sql.streaming.StreamingQueryManager.startQuery(StreamingQueryManager.scala:251)
at org.apache.spark.sql.streaming.DataStreamWriter.start(DataStreamWriter.scala:287)
at org.apache.spark.sql.streaming.DataStreamWriter.start(DataStreamWriter.scala:231)
不是您对象的副本。您应该编写一个方法,使用与myCopiedObject
相同的值创建MyObject
的新实例。
答案 1 :(得分:2)
var myCopiedObject = iMyObject
上面的代码不会创建对象的副本。您基本上是指同一个对象,但使用不同的参考。
使用case class
并使用copy
方法创建包含所需更改的副本
case class Something(list: List[Int])
val sthing = Something(List(1, 2))
val copy = sthing.copy(list = sthing.list.take(1)) //creating changed copy using copy method