Home > Back-end >  List ending with all elements being equal in Kotlin, interesting case
List ending with all elements being equal in Kotlin, interesting case

Time:08-25

I stumbled with an interesting case where i have something like this in the OnCreate method of my main activity:

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 is just this:

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

Can someone explain to me why would the logs on the first for print correctly 0 to 15 but the logs in the second for are printing all equal ids?

CodePudding user response:

You are adding reference to the same variable in memory to list - in the end you have list of 16 identical objects.

First log function call shows you untruthfully valid behavior, because you are printing temporary value with every for loop iteration, but in second Log call you are printing final values. The same object must have the same values of the same field.

CodePudding user response:

You have an object, temp, right? In the first loop, you're doing something to that object. Then you add it to the list - or to be more accurate, you add a reference to it to that list, something that points at your object.

Have a think about what the final list will look like. I'm gonna explain what's going on, but it's worth thinking about it first!


So you have your temp object. It looks like it's an object inside the TestObject class, so just a single object. You're not creating any new instances of it, you're just working with the same object the whole time.

As you loop, you change the id property on temp, and add temp to the list. This is a reference to the object, something that points at temp itself - it's not a new, separate copy of temp. You're not creating a snapshot of its current state. There's one object, and a bunch of references all pointing to it.

So as you increment temp.id, every item in your list will "see" that change - because every item is that specific object. You just have multiple references to it. When you finish (and when the second logging loop runs) you have 16 items, all that specific temp object, whose id value is now 15.

You can probably work out the logging behaviour now! (I'm sure the question's already been answered anyway)

CodePudding user response:

object keyword means creating a Singleton object - an object which has only one instance in a program. In the first cycle InnerObject.id is changed for the same object and during that the logs print all the values. After the first cycle is finished the last value is set to InnerObject.id that is 15. In the second cycle you just print that value.

  • Related