Изменяемый массив переопределяется при добавлении в другую переменную - PullRequest
0 голосов
/ 12 января 2019

У меня есть простой случай, когда у меня есть «Список A» с 5 значениями, а другой «Список B» действует как TempList, содержащий значения «Список A» теперь, когда я вызываю "list_A.clear ()"
"list_B" также очищается почему?

val List_A: MutableList<String> = ArrayList<String>()


List_A.add("index_1")
List_A.add("index_2")
List_A.add("index_3")
List_A.add("index_4")
List_A.add("index_5")

val  List_B = List_A
List_A.clear()

Результат

List_A-----Size--------> 0
List_B-----Size--------> 0

Обратите внимание, что он работает, как и ожидалось, когда я определяю "List_B" как

var List_B: MutableList<String> = ArrayList<String>()
  then
List_B.addAll(List_A) 

Результат

List_A-----Size--------> 0
List_B-----Size--------> 5

Передает ли kotlin переменную List_A Referance в List_B?

Ответы [ 3 ]

0 голосов
/ 12 января 2019

Передает ли kotlin переменную List_A Referance в List_B?

Точно. И List_A, и List_B относятся к одному и тому же адресу в памяти. Если вы хотите сделать копию, вам нужно создать новый ArrayList и добавить в него все элементы с помощью addAll. После этого вы можете очистить List_A.

Пример

val listA: MutableList<String> = mutableListOf("index_0", "index_1", "index_2")
val listB: MutableList<String> = mutableListOf()
listB.addAll(listA)
listA.clear()

Хотя в вашем случае это будет нормально работать с String, вы должны понимать, что новый список содержит те же объекты (ссылки на те же объекты), а не их копию. Поэтому, если вы не очистите listA и не измените его элемент, этот элемент также будет изменен в listB соответственно.

0 голосов
/ 12 января 2019

listA и listB оба хранят одну и ту же ссылку, когда вы звоните clear().

Вам нужно сделать копию listA, позвонив по номеру toMutableList().

val listA = ArrayList<String>()

listA.add("index_1")
listA.add("index_2")
// ...

val listB = listA.toMutableList()
listA.clear()
// listB will be unchangend

Примечание:

  • Вы должны придерживаться соглашений о присвоении имен Kotlin, поэтому ваши переменные должны быть в верблюжьем регистре без подчеркивания.
  • Тип listA может быть выведен, поэтому нет необходимости явно указывать тип.
0 голосов
/ 12 января 2019

Когда вы создаете объект и назначаете ссылку на этот объект для List_A , для этого объекта выделяется память, и у нее есть некоторый адрес, скажем, @ eae072e . List_A является ссылкой на этот объект. Когда вы создаете переменную List_B и присваиваете ей List_A , они оба ссылаются на один и тот же адрес в памяти @ eae072e . Поэтому, когда вы используете один из них для манипулирования данными, эта манипуляция будет отражена в обоих из них - в List_A и List_B .

Чтобы избежать этого, следует создать новый экземпляр List_B :

var List_B: MutableList<String> = ArrayList<String>()
List_B.addAll(List_A) 

И тогда вы можете очистить список List_A , и он не будет отражен в List_B :

List_A.clear() 
// List_A is empty, List_B will contain items
...