How can I duplicate an object to another object, without changing the base object in Kotlin?

22,471

Solution 1

You are just assigning the same object (same chunk of memory) to another variable. You need to somehow create a new instance and set all fields.

header2 = Record()
header2.name = header1.name

However in Kotlin, if the Record class was Data class, Kotlin would create a copy method for you.

data class Record(val name: String, ...)
...
header2 = header1.copy()

And copy method allows you to override the fields you need to override.

header2 = header1.copy(name = "new_name")

Solution 2

If your Class is not a Data Class and your project has Gson and you want to copy the whole object ( probably edit after getting it ), Then if all those conditions are true then this is a solution. This is also a DeepCopy. ( For a data Class you can use the function copy()).

Then if you are using Gson in your project. Add the function copy():

class YourClass () {

// Your class other stuffs here

  fun copy(): YourClass { //Get another instance of YourClass with the values like this!
      val json = Gson().toJson(this)
      return Gson().fromJson(json, YourClass::class.java)
  }
}

If you want to install Gson then get the latest version here.

Solution 3

You got 2 options use the copy method if the second object needs to be exactly the same or some of a fields needs to be changed.

val alex = User(name = "Alex", age = 1)
val olderAlex = alex.copy(age = 2)

or Kotlin got the great syntax of constructing object I mean, e.g.

createSomeObject(obj = ObjInput(name = objName,
                    password = UUID.randomUUID().toString()
                    type = listOf(TYPE)))

In fact, It seems to be easier in your case use first one but good to know about the second way to resolve this task.

Share:
22,471

Related videos on Youtube

SadeQ digitALLife
Author by

SadeQ digitALLife

Updated on August 01, 2022

Comments

  • SadeQ digitALLife
    SadeQ digitALLife over 1 year

    this is my code:

    var header1: Record? = null
    var header2: Record? = null
    
    header2 = header1
    header2.name = "new_name"
    

    but header1.name changes too!

    • Uberto
      Uberto almost 6 years
      the correct answer is using copy() but I suggest you not to use var at all and instead use val with the correct constructor for header. If you need to create 2 objects almost identical apart one field or two, just create a function fun buildHeader(name: String): Record {...} val header1 = buildHeader("name1") val header2 = buildHeader("name2")
  • Ruslan Berozov
    Ruslan Berozov almost 5 years
    But how can I do it again? How can I copy all params from one object to another immutable object if it is already instantiated?
  • Josef Adamcik
    Josef Adamcik almost 5 years
    @RuslanBerozov you cannot, immutable means you cannot change the instance. Therefore you cannot copy values to the already instantiated object in such case. But it's most likely you don't need to.
  • Ruslan Berozov
    Ruslan Berozov almost 5 years
    @jocef-adamcik there are some situations when I need to do that. For example - I need to update item in "currentList" in PagedListAdapter. I did it with custom function in data class of item.
  • Josef Adamcik
    Josef Adamcik almost 5 years
    @RuslanBerozov If you really need to, you have to use mutable objects. Usually, I would aim to use immutable objects and replace the instance in the list. But I have no experience with PageListAdapter in particular and I am not sure what are all the limitations there. Also, your situation would be most likely even more specific. I don't think it is possible and/or makes sense to try to figure it out here in comments. Consider making a SO question for your situation.
  • Alan Nelson
    Alan Nelson over 3 years
    This seems very hacky to me. Are there any downsides to using this?
  • Xenolion
    Xenolion over 3 years
    Its more like Gson was made to copy and retrieve classes, so you make use of that feature.
  • Rafael Chaves
    Rafael Chaves about 3 years
    @AlanNelson This would only work in cases where the object in question can be serialized and deserialized using Gson. That breaks down with collections, for instance. Also, Gson would not know when to stop, so it would perform a deep clone, and it would clone even state that you wanted to be shared between the source and copy objects.
  • Anna T
    Anna T almost 3 years
    Question is about Kotlin specifically, not Java.