【问题标题】:How to clone or copy a 2d list in kotlin如何在 kotlin 中克隆或复制二维列表
【发布时间】:2021-10-25 10:59:09
【问题描述】:

来自here

下面为测试用例提供

@Test
fun testKotlinArrayCopy() {

    data class Person(val name: String, var friends: List<Person>, var isHungry: Boolean = false)

    val okyFriends = listOf(
        Person(name = "Billy", friends = listOf()),
    )

    val peopleAtBlock1 : ArrayList<Person> = arrayListOf(
        Person(name = "Oky", friends = okyFriends),
    )

    val peopleAtBlock2 : ArrayList<Person>  = ArrayList(peopleAtBlock1.toMutableList())


    peopleAtBlock1[0].friends[0].isHungry = true
    
    // here i expect variable peopleAtBlock2 doesn't changed 
    // because i just change the peopleAtBlock1 only
    assertFalse(peopleAtBlock1[0] == peopleAtBlock2[0])
    
}

当我运行测试时,它失败了,因为 peopleAtBlock2 由此代码导致意外更改

peopleAtBlock1[0].friends[0].isHungry = true

我想保持peopleAtBlock2 的值不变,我该怎么做?

谢谢

编辑

我已经关注答案here 使用

fun Array<BooleanArray>.copy() = map { it.clone() }.toTypedArray()

转换为我的情况,函数将是

fun ArrayList<Person>.copy2() = map { it.copy() }.toTypedArray()

还是不行

如果您没有 kotlin,请检查 my repl 是否在云中运行

【问题讨论】:

标签: list kotlin arraylist copy


【解决方案1】:

在您的情况下,peopleAtBlock2shallow copypeopleAtBlock1,这意味着它们引用相同的对象。因此,当您更改 peopleAtBlock1 中对象的值时,它也会反映在 peopleAtBlock2 中。

为了解决这个问题,您必须创建 peopleAtBlock1 的深层副本。 recommended way 这样做是使用序列化。也就是先序列化原始数据,然后通过反序列化创建副本。

有更好的方法可以做到这一点,但一种快速简便的方法是使用 JSON 序列化,可以按照以下步骤完成

首先在你的项目中为Gson添加依赖

implementation 'com.google.code.gson:gson:2.8.8'

现在将Person 类移到函数外,Gson 不适用于本地类

最后你可以创建一个深拷贝

val type = object : TypeToken<ArrayList<Person>>(){}.type
val json = Gson().toJson(peopleAtBlock1, type)
val peopleAtBlock2 = Gson().fromJson<ArrayList<Person>>(json, type)

【讨论】:

  • 它现在可以工作了,感谢您的详细回答。我想知道为什么 kotlin/java 不为所有对象提供 deepclone ..
【解决方案2】:
fun Person.deepCopy(): Person = copy(friends = friends.map { it.deepCopy() })

val peopleAtBlock2 = peopleAtBlock1.map { it.deepCopy() }

【讨论】:

    猜你喜欢
    • 2018-04-01
    • 2014-05-23
    • 2019-05-09
    • 2015-05-21
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-11
    相关资源
    最近更新 更多