web-dev-qa-db-ja.com

Kotlinのオブジェクトを含むリストのディープコピー

私はkotlinを初めて使い、オブジェクトのリストのコピーを作成しようとしていますが、新しいコピーのアイテムを変更すると、古いリストも変更されるという問題があります。これはオブジェクトです:

class ClassA(var title: String?, var list: ArrayList<ClassB>, var selected: Boolean)
class ClassB(val id: Int, val name: String) 

私はこれを試しましたが、うまくいきません:

val oldList:ArrayList<ClassA>


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

すべてのオブジェクト参照を別のリストに追加しているため、適切なコピーを作成していないため、2つのリストに同じ要素があります。異なるリストと異なる参照が必要な場合は、新しいリストのすべてのオブジェクトを複製する必要があります。

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

ArrayListオブジェクトで使用できる拡張関数を作成できます。

fun ArrayList<Int>.copy() : ArrayList<Int> {
    val arr = ArrayList<Int>()
    for(i in this) {
        arr.add(i)
    }
    return arr
}

使用法:

arrayList.copy()

ターゲットArrayListでIntsを使用していない場合は、拡張機能でIntsを変更するだけです。

1
Lukas Schneider

これはkotlinとは関係ありません。古いリストから新しいリストにオブジェクトを追加するとき、それらに参照を追加します(新しいオブジェクトを作成しない)。つまり、メモリ内のアドレスを新しいリストにコピーするだけです。 。

この問題を修正するには、オブジェクトごとに新しいインスタンスを作成する必要があります。たとえば、コピーコンストラクターを作成できます。

constructor(otherA: ClassA) {
    this.prop1 = otherA.prop1
    this.prop2 = otherA.prop2
    ...
} 

次に、それらを1つずつ新しいリストに追加します。

list1.forEach { list2.add(Class(it)) }
0
Roi Amiel

オブジェクトの反復に「to」を使用

リスト-> toList()

配列-> toArray()

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

ログの印刷:

array: 4
arrayCopy: 4
array after remove: 3
arrayCopy after remove: 4
0
Rasoul Miri