列表以Kotlin中所有元素相等结尾,这是一个有趣的例子



我偶然发现了一个有趣的案例,在我的主要活动的OnCreate方法中有这样的东西:

val list = mutableListOf<TestObject.InnerObject> ()
val temp = TestObject.InnerObject
for (i in 0..15)
{
temp.id = i
Log.i ("id", temp.id)
list.add (temp)
}
for (element in list)
{
Log.i ("id", element.id)
}

TestObject就是这样:

object TestObject { 
object InnerObject { 
var id = 0 
}
}

有人能向我解释一下,为什么第一个for的日志会正确打印0到15,而第二个for的记录会打印所有相同的id吗?

您有一个对象temp,对吗?在第一个循环中,您正在对该对象执行某些操作。然后你把它添加到列表中,或者更准确地说,你把对它的引用添加到该列表中,指向你的对象。

想一想最终的名单会是什么样子。我会解释发生了什么,但值得先想想!


所以您有了temp对象。它看起来像是TestObject类中的一个object,所以只是一个对象。你没有创建任何新的实例,你只是一直在使用同一个对象

循环时,更改temp上的id属性,并将emp添加到列表中。这是对对象的引用,指向temp本身-它不是temp新的独立副本。您没有创建其当前状态的快照。有一个对象,还有一堆引用都指向它

因此,当你增加temp.id时,你列表中的每一项都将";参见";这种变化——因为每一项都是特定的对象。您只是有多个对它的引用。当您完成(以及第二个日志循环运行时(时,您有16项,所有特定的temp对象,其id值现在是15

你现在可能可以计算出日志行为了!(我相信这个问题已经得到了回答(

您正在添加对内存中相同变量的引用以列出-最后您有16个相同对象的列表。

第一个log函数调用显示了不真实有效的行为,因为每次for循环迭代都要打印临时值,但是在第二次Log调用中,您将打印最终值。同一对象在同一字段中必须具有相同的值。

object关键字意味着创建一个Singleton对象——一个程序中只有一个实例的对象。在第一个周期中,CCD_ 12对于同一对象被改变,并且在此期间日志打印所有值。在第一个周期结束之后,最后一个值被设置为InnerObject.id,即15。在第二个循环中,您只需打印该值。

在同一对象temp中,您正在修改id。所以在第一个循环中,它打印0到15,但在下一个循环中它打印的是您指定为主要对象的最后一个值。如果您想要不同的值,则需要创建TestObject的新对象并分配该值。

最新更新