I'm adding new items to mutable list by setting header and detail data in val production
.
val productionList = mutableListOf<ProductionData>()
val production = ProductionData()
//Assign header data
production.dateHeader = headerData.date
production.timeHeader = headerData.time
//Iterate detail data
for (item in detailData) {
//Assign detail data
production.timeDetail = item.timeDetail
//Add new product
productionList.add(production)
}
The problem is that on second iteration, production.timeDetail
is modified but the productionList[0]
is also modified.
How can I add items by value and not by reference as it is now? What am I doing wrong?
CodePudding user response:
There is no support for adding to a list by value in Kotlin. A List can only hold references to classes.
Kotlin does have something called inline classes that can be passed by value under some circumstances, but they cannot be stored in Lists as values. Lists exclusively store references. The primitive classes (Byte, Char, Int, Long, Double, Float) are inline classes that have special array types (e.g. IntArray
) that can hold actual values instead of references, but there is no way to do this for any other types of inline class. Notably, inline classes are all immutable, so you usually don't even have to think about whether they're being used as references versus as values except when you're optimizing code performance.
The standard generic Array
type can only hold references.
You must manually copy objects into new instances if you want to modify what's in a list without modifying the original instance. If your class is a data class
, it has a built-in copy()
function for this purpose. See here for documentation about how this works.
It is common for robustness reasons to make your data classes immutable, which means that all of their properties are val
instead of var
. Then you cannot accidentally mutate a reference.