KotlinHow to,,deep”复制数组,这样我有两个相同的数组,但它们引用不同的内存位置(它们不包含相同的对象)

8hhllhi2  于 2022-11-25  发布在  Kotlin
关注(0)|答案(1)|浏览(109)

我需要遍历一个数组并改变它的对象,但我仍然需要引用原始数组,所以我需要原始数组的副本来改变它的对象,然后在操作完成后,我想把原始数组改变成(复制的)改变后的数组。大小和对象将是相同的,但它们的值将改变。
非常感谢您的时间和帮助提前。

**我的问题是:**当我复制原始数组时,副本和原始数组都引用内存中的相同位置,因此对象的状态发生更改,我的代码无法正确完成其任务。如何复制数组,使副本引用内存中的其他位置,但对象相同?

简单的var copyArray = originalArray显然不起作用。我在网上彻底搜索了一下,在Kotlin中找不到我问题的确切答案。

64jmpszr

64jmpszr1#

**选项1:**由于您的对象只有一个级别的属性,因此浅层副本与深层副本一样有效。如果它有多个级别,您仍然可以使用copy()方法,但必须显式指定如何复制每个特定属性。

val arrayOfArrays2 = arrayOfArrays.map { arrayOfCells -> arrayOfCells.map { it.copy() }  }

完整代码:

fun main() {
    val cell1 = Cell(true)
    val cell2 = Cell(false)
    val arrayA = arrayOf(cell1, cell2)

    val arrayOfArrays = arrayOf(arrayA, arrayA)
    val arrayOfArrays2 = arrayOfArrays.map { arrayOfCells -> arrayOfCells.map { it.copy() }  }

    arrayOfArrays[0][0].isAlive = false;

    arrayOfArrays.forEach { it.forEach { println("ArrayA: $it") } }
    println()
    arrayOfArrays2.forEach { it.forEach { println("ArrayB: $it") } }
}

结果是:

ArrayA: Cell(isAlive=false)
ArrayA: Cell(isAlive=false)
ArrayA: Cell(isAlive=false)
ArrayA: Cell(isAlive=false)

ArrayB: Cell(isAlive=true)
ArrayB: Cell(isAlive=false)
ArrayB: Cell(isAlive=true)
ArrayB: Cell(isAlive=false)

**选项2:**您可以序列化和还原序列化对象。

将以下依赖项添加到build.gradle:

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

在单元格类中创建一个deepCopy函数:

import com.google.gson.Gson

data class Cell(
    var isAlive: Boolean
) {
    fun deepCopy(): Cell {
        val json = Gson().toJson(this)
        return Gson().fromJson(json, Cell::class.java)
    }
}

和代码进行测试:

fun main() {
    val cell1 = Cell(true)
    val cell2 = Cell(false)
    val arrayA = arrayOf(cell1, cell2)
    val arrayB = arrayA.map { it.deepCopy() }.toTypedArray()
    cell1.isAlive = false
    println(arrayA.contentToString())
    println(arrayB.contentToString())
}

输出量:

[Cell(isAlive=false), Cell(isAlive=false)]
[Cell(isAlive=true), Cell(isAlive=false)]

此外,由于您有一个2D数组:

fun main() {
    val cell1 = Cell(true)
    val cell2 = Cell(false)
    val arrayA = arrayOf(cell1, cell2)

    val arrayOfArrays = arrayOf(arrayA, arrayA)
    val arrayOfArrays2 = arrayOfArrays.map { arrayOfCells -> arrayOfCells.map { it.deepCopy() } }.toTypedArray()

    arrayOfArrays[0][0].isAlive = false;

    arrayOfArrays.forEach { it.forEach { println("ArrayA: $it") } }
    println()
    arrayOfArrays2.forEach { it.forEach { println("ArrayB: $it") } }
}

结果是:

ArrayA: Cell(isAlive=false)
ArrayA: Cell(isAlive=false)
ArrayA: Cell(isAlive=false)
ArrayA: Cell(isAlive=false)

ArrayB: Cell(isAlive=true)
ArrayB: Cell(isAlive=false)
ArrayB: Cell(isAlive=true)
ArrayB: Cell(isAlive=false)

相关问题