Deep copy of list with objects in Kotlin

后端 未结 4 1558
夕颜
夕颜 2020-12-18 19:22

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

相关标签:
4条回答
  • 2020-12-18 19:48

    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)) }
    
    0 讨论(0)
  • 2020-12-18 19:59

    Use 'to' for iterate object

    List -> toList()

    Array -> toArray()

    ArrayList -> toArray()

    MutableList -> toMutableList()


    Example:

    val array:ArrayList<String> = ArrayList()
    array.add("1")
    array.add("2")
    array.add("3")
    array.add("4")
    
    val arrayCopy = array.toArray() // copy array to other array
    
    Log.i("---> array " ,  array?.count().toString())
    Log.i("---> arrayCopy " ,  arrayCopy?.count().toString())
    
    array.removeAt(0) // remove first item in array 
    
    Log.i("---> array after remove" ,  array?.count().toString())
    Log.i("---> arrayCopy after remove" ,  arrayCopy?.count().toString())
    

    print log:

    array: 4
    arrayCopy: 4
    array after remove: 3
    arrayCopy after remove: 4
    
    0 讨论(0)
  • 2020-12-18 20:00

    There is no default function in Kotlin to do this. I have done using Gson.

    public data class Person{
      val id = 1
      val name = ""
      public Person copy(){
            String stringPerson = new Gson().toJson(this, Person.class);
            return new Gson().fromJson(stringPerson, Person.class);
        }
    }
    
    val persone = Person()
    persone.id = 1
    person.name = "ABC"
    val originalList = ArrayList()
    list1.add(persone)
    val copiedList = originalList.map{it.copy()}
    list2.get(0).name = "DEF"
    

    It will not update the originaList. Changes will only reflect in the copiedList.

    0 讨论(0)
  • 2020-12-18 20:07

    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)]
    
    0 讨论(0)
提交回复
热议问题