当被断言到另一个变量时,可变数组被覆盖

Posted

技术标签:

【中文标题】当被断言到另一个变量时,可变数组被覆盖【英文标题】:Mutable array get overridden when get asserted to another variable 【发布时间】:2019-06-07 03:40:52 【问题描述】:

我有一个简单的案例,我有一个包含 5 个值的“列表 A”,另一个“列表 B”充当持有“列表 A”值的 TempList 现在当我调用“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 变量引用传递给 List_B ?

【问题讨论】:

【参考方案1】:

listAlistB 在您调用 clear() 时都持有相同的引用。

您需要做的是通过调用toMutableList() 复制listA

val listA = ArrayList<String>()

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

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

注意:

您应该遵守 Kotlin 的命名约定,因此您的变量应该是驼峰式大小写,没有下划线。 listA 的类型是可以推断出来的,所以不需要明确指定类型。

【讨论】:

【参考方案2】:

当您创建一个对象并将对该对象的引用分配给 List_A 时,会为该对象分配一个内存并且它有一些地址,例如 @eae072eList_A 是对该对象的引用。当您创建一个变量 List_B 并分配给它 List_A 时,它们都引用了内存中的相同地址 @eae072e。因此,当您使用其中一个来操作数据时,这种操作将反映在它们两者中 - 在 List_AList_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

【讨论】:

根据您的回答,如果我理解“堆栈内存”可以有两次相同的地址,谢谢... 两个变量可以引用内存中的同一个地址。【参考方案3】:

kotlin 是否将 List_A 变量引用传递给 List_B ?

没错。 List_AList_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 中的该元素也会相应地更改。

【讨论】:

dosen't Kotlin Pass variable By value Like Java as it uses the same JVM and why declarign List_B not create new Adress in memory 谢谢你的回应..

以上是关于当被断言到另一个变量时,可变数组被覆盖的主要内容,如果未能解决你的问题,请参考以下文章

Java实现长度可变数组

Swift - GCD 可变数组多线程发出“在枚举时发生突变”

可变参数

可变数组怎么初始化(可变大小的对象不能被初始化)?

Array 与 NSArray 的不同点对比表

无法将元素添加到 kotlin 中可变列表的数组数组