Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Kotlin中包含对象的列表的深度副本_Android_Kotlin_Kotlin Android Extensions_Kotlin Extension - Fatal编程技术网

Android Kotlin中包含对象的列表的深度副本

Android Kotlin中包含对象的列表的深度副本,android,kotlin,kotlin-android-extensions,kotlin-extension,Android,Kotlin,Kotlin Android Extensions,Kotlin Extension,我是kotlin的新手,我正在尝试制作对象列表的副本。我遇到的问题是,当我更改新副本中的项目时,旧列表也会更改。这就是目标: class ClassA(var title: String?, var list: ArrayList<ClassB>, var selected: Boolean) class ClassB(val id: Int, val name: String) ClassA类(变量标题:String?,变量列表:ArrayList,所选变量:Boolean)

我是kotlin的新手,我正在尝试制作对象列表的副本。我遇到的问题是,当我更改新副本中的项目时,旧列表也会更改。这就是目标:

class ClassA(var title: String?, var list: ArrayList<ClassB>, var selected: Boolean)
class ClassB(val id: Int, val name: String) 
ClassA类(变量标题:String?,变量列表:ArrayList,所选变量:Boolean)
类B(val id:Int,val名称:String)
我试过这样做,但不起作用:

val oldList:ArrayList<ClassA>


val newList :ArrayList<ClassA> = ArrayList()
newList.addAll(oldList)
val oldList:ArrayList
val newList:ArrayList=ArrayList()
newList.addAll(oldList)

这是因为您正在将所有对象引用添加到另一个列表,因此您没有制作正确的副本,两个列表中有相同的元素。如果要使用不同的列表和不同的引用,则必须克隆新列表中的每个对象:

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)]
list1.forEach { list2.add(Class(it)) }
公共数据类人员(变量n:String)
趣味主线(args:Array){
//创建两个实例
var anna=个人(“anna”)
var Alex=个人(“Alex”)
//添加到列表中
val names=arrayOf(安娜,亚历克斯)
//生成新的真实克隆列表
val cloneNames=names.map{it.copy()}
//修改第一个列表
cloneNames.get(0).n=“另一个安娜克隆”
println(names.toList())
println(cloneNames.toList())
}
[个人(n=Anna),个人(n=Alex)]
[个人(n=另一个安娜克隆人),个人(n=亚历克斯)]

这与kotlin无关,当您将旧列表中的对象添加到新列表中时,它会添加对它们的引用(不创建新对象),这意味着它只是将内存中的地址复制到新列表中

要解决此问题,应为每个对象创建一个新实例。您可以创建副本构造函数,例如:

constructor(otherA: ClassA) {
    this.prop1 = otherA.prop1
    this.prop2 = otherA.prop2
    ...
} 
然后将它们逐个添加到新列表中:

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)]
list1.forEach { list2.add(Class(it)) }

对迭代对象使用“to”

列表->列表()

阵列->阵列()

ArrayList->toArray()

MutableList->toMutableList()


示例:

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())

Kotlin中没有执行此操作的默认函数。 我已经用过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"
它不会更新原创者。
更改只会反映在复制列表中。

检查此项,这是错误的。它只适用于不可变的东西,比如int或string。嘿@Dam,如果这个类不是数据类呢?如何使用不同的哈希代码进行克隆?这样可以节省时间。Alhamdulillah这会做深度复制吗?@IgorGanapolsky这只会深度复制已知的类成员。甚至这个答案也有一个流程。
列表
中的所有对象都是“深度复制”的,但
列表
中没有引用自身<代码>列表仍然指向相同的内存位置,只是其内容已更改。如果您向类中添加了另一个列表,而忘记将此处提到的相同步骤应用于新的
列表
,您仍然会感到头痛。所以不,这不是一个通用的深度复制解决方案,只是一个针对特定用例的解决方案(变通方法)