TL,DR
I have a Kotlin code where elements are added to arraylist but the list is not storing the new value although the return for the function shows the changed list.
Example problem:
/* someList = ["A", "ab"] */
val x = someList.plus("Abc")
Example output:
someList = ["A", "ab"] , x = ["A", "ab", "Abc"]
Full Problem
My code:
class FriendClass{
/* others */
@JsonProperty("messages")
var messages: List<String>? = ArrayList()
}
class DataClass{
/* singleton */
/* others */
@JsonProperty("friend_detail_list")
var friendDetailList: List<FriendClass> = ArrayList()
}
class Adapter{
val a = DataClass.getInstance().friendDetailList[0].messages?.plusElement("Hello")
val b = DataClass.getInstance().friendDetailList[0].messages
val c = DataClass.getInstance().friendDetailList[0].messages?.toMutableList().add("Hello")
val d = DataClass.getInstance().friendDetailList[0].messages
/* printing a, b, c, d */
}
My output:
messages
already had ["a", "bcd", "xfd"]
Now after printing the results are:
a = ["a", "bcd", "xfd", "Hello"]
b = ["a", "bcd", "xfd"]
a = true
b = ["a", "bcd", "xfd"]
How dow I make the original messages
update it's values in the FriendClass
?
Check the signature of the function:
@kotlin.internal.InlineOnly
public inline fun <T> Iterable<T>.plusElement(element: T): List<T> {
return plus(element)
}
/**
* Returns a list containing all elements of the original collection and then the given [element].
*/
public operator fun <T> Collection<T>.plus(element: T): List<T> {
val result = ArrayList<T>(size + 1)
result.addAll(this)
result.add(element)
return result
}
It's clear from this that it doesn't modify the original list. What you want instead is probably:
val messages = DataClass.getInstance().friendDetailList[0].messages
DataClass.getInstance().friendDetailList[0].messages = messages.plusElement("Hello")
This will work because messages
is mutable (declared with var
).
There's a great article about some of these gotchas here.