Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deep copy of list with objects in Kotlin

I am new to kotlin and I am trying to make a copy of a list of objects.The problem I am having is that when I change items in the new copy, the old list gets changed as well. This is the object:

class ClassA(var title: String?, var list: ArrayList<ClassB>, var selected: Boolean)
class ClassB(val id: Int, val name: String) 

I tried doing this, but it doesn't work:

val oldList:ArrayList<ClassA>


val newList :ArrayList<ClassA> = ArrayList()
newList.addAll(oldList)
like image 936
Oya Avatar asked Jul 23 '18 13:07

Oya


People also ask

What is deep copy in Kotlin?

There is a way to make a deep copy of an object in Kotlin (and Java): serialize it to memory and then deserialize it back to a new object. This will only work if all the data contained in the object are either primitives or implement the Serializable interface.

How do you make a deep copy of nested objects?

assign() was the most popular way to deep copy an object. Object. assign() will copy everything into the new object, including any functions. Mutating the copied object also doesn't affect the original object.


3 Answers

That's bacause you are adding all the object references to another list, hence you are not making a proper copy, you have the same elements in two list. If you want diferents list and diferent references, you must clone every object in a new list:

public data class Person(var n: String)  fun main(args: Array<String>) {     //creates two instances     var anna = Person("Anna")     var Alex =Person("Alex")      //add to list     val names = arrayOf(anna , Alex)     //generate a new real clone list     val cloneNames = names.map{it.copy()}      //modify first list     cloneNames.get(0).n = "Another Anna clone"      println(names.toList())     println(cloneNames.toList()) }  [Person(n=Anna), Person(n=Alex)] [Person(n=Another Anna clone), Person(n=Alex)] 
like image 116
A Monad is a Monoid Avatar answered Sep 19 '22 02:09

A Monad is a Monoid


var oldList: List<ClassA>?  val newList = oldList.map { it.copy() }
like image 45
Yasin Ege Avatar answered Sep 20 '22 02:09

Yasin Ege


This is not related to kotlin, when you are adding the objects from the old list to the new one, it add the reference to them (no createing a new object ), whats mean it just copying the address in the memory to the new list.

To fix this problem you should create a new instance for each object. you can create a copy constructor, for example:

constructor(otherA: ClassA) {
    this.prop1 = otherA.prop1
    this.prop2 = otherA.prop2
    ...
} 

and then add them one by one to the new list:

list1.forEach { list2.add(Class(it)) }
like image 32
Roi Amiel Avatar answered Sep 21 '22 02:09

Roi Amiel