1

我有一个这样的数据类

data class Person(val id: Long = BaseDataContract.BaseData.UNDEFINED_ID.toLong(),
              .....
              val personConsents: ArrayList<PersonConsent> = ArrayList<PersonConsent>()) 

我有两个对象副本:

person = originalPerson.copy()

然后我更改对象 person 的 personConsents 元素 - 我添加/删除/编辑它们。但由于某种原因,我看到 originalPerson 对象中发生了我不想成为的相同变化。originalPerson 根本不应该改变。怀疑 ArrayList 引用有问题,但需要你的建议我能做什么?最后,我需要比较像fun dataChanged(): Boolean = originalPerson != personbu 这样的两个对象,当 ArrayList 发生变化时它不起作用。

4

3 回答 3

2

我找到了一个简单的解决方案。我使用自己的克隆函数为 ArrayList 创建一个新对象并用复制的元素填充它。

fun getPersonClone(person: Person): Person {
    val personConsents: ArrayList<PersonConsent> = ArrayList<PersonConsent>()
    person.personConsents.forEach { personConsents.add(it.copy()) }
    return Person(person.id, ......., personConsents)
}
于 2018-02-08T10:18:17.887 回答
1

所以,这里的这个链接,将帮助你理解copyKotlin 中的方法,不做深拷贝,它只做浅拷贝。这在非原始数据类型(例如ArrayList您正在使用的数据类型)中特别常见。

如果一定要用方法直接拷贝数据类,可以先序列化,再反序列化。

我在下面做了类似的事情,使用Gson.

使用数据类

 data class Person(var name: String? = null,val cars : ArrayList<String> = ArrayList() )

主要方法

fun main (args: Array<String>) {

    var original =Person("Jon", arrayListOf("Honda City","VW Vento"))
    var clone =Gson().fromJson(Gson().toJson(original), Person::class.java)
    original.cars.add("VW Polo")
    original.name = "Henry"
    print(clone.cars) // Prints [Honda City, VW Vento]   

}

这种方法看起来真的很hacky,我会鼓励任何更好的方法。

于 2018-02-08T09:18:43.000 回答
0

Kotlin 复制方法是浅复制。因此,您的副本最终会引用与原始对象完全相同的数组。

我想说解决这个问题的最简单方法是自己实现复制方法(无需创建额外的自定义克隆方法):

data class Person(val id: Long = BaseDataContract.BaseData.UNDEFINED_ID.toLong(), val personConsents: ArrayList<PersonConsent> = ArrayList<PersonConsent>()) {
    fun copy() = Person(this.id, ArrayList(this.personConsents))
}
于 2018-02-08T23:29:58.533 回答