Reputation:
I don't want to modify oldList
I want to change only newList
but whenever i change newList
, oldList
also modified.
please help.
data class Cat(
val id: String,
var image: String
var details: String
)
fun main() {
val oldList= listOf(
Cat("id1", "img1", "details1"),
Cat("id2", "img2", "details1"),
Cat("id3", "img3", "details1"),
)
println(list)
val newList = oldList
newList.onEach {
cat ->
cat.image = "web_" + cat.image
cat.details= "detail_xyz" + cat.details
}
println(newList)
println(list)
}
Upvotes: 1
Views: 860
Reputation: 941
You must make a deep copy of the list to prevent the current situation. Your current situation is that the two lists share the same reference, so the current phenomenon has occurred.
data class Cat(
val id: String,
var image: String,
var details: String
)
fun main() {
val oldList= listOf(
Cat("id1", "img1", "details1"),
Cat("id2", "img2", "details1"),
Cat("id3", "img3", "details1")
)
println(oldList)
val newList = oldList.toMutableList()
newList.onEach {
cat ->
cat.image = "web_" + cat.image
cat.details= "detail_xyz" + cat.details
}
println(newList)
println(oldList)
}
The result of the operation is:
[Cat(id=id1, image=img1, details=details1), Cat(id=id2, image=img2, details=details1), Cat(id=id3, image=img3, details=details1)]
[Cat(id=id1, image=web_img1, details=detail_xyzdetails1), Cat(id=id2, image=web_img2, details=detail_xyzdetails1), Cat(id=id3, image=web_img3, details=detail_xyzdetails1)]
[Cat(id=id1, image=web_img1, details=detail_xyzdetails1), Cat(id=id2, image=web_img2, details=detail_xyzdetails1), Cat(id=id3, image=web_img3, details=detail_xyzdetails1)]
I think I found the reason, toMutableList() is actually capable of deep copying. But as for why my code didn’t work, the reason is: MutableList data is an object reference, which leads to changes in the elements in MutableList will still lead to changes in the original elements, which has nothing to do with List and MutableList, just object references Caused by multiplexing.
So if you want to solve the secondary problem: you need to make a deep copy on the basis of the object. In this way, the new data cannot affect the original data.
data class Cat(
val id: String,
var image: String,
var details: String
)
fun main() {
val oldList = listOf(
Cat("id1", "img1", "details1"),
Cat("id2", "img2", "details1"),
Cat("id3", "img3", "details1")
)
println(oldList)
val newList = mutableListOf<Cat>()
oldList.apply {
onEach { cat ->
newList.add(cat.copy().apply {
image = "web_$image"
details = "detail_xyz$details"
})
}
}
println(newList)
println(oldList)
}
[Cat(id=id1, image=img1, details=details1), Cat(id=id2, image=img2, details=details1), Cat(id=id3, image=img3, details=details1)]
[Cat(id=id1, image=web_img1, details=detail_xyzdetails1), Cat(id=id2, image=web_img2, details=detail_xyzdetails1), Cat(id=id3, image=web_img3, details=detail_xyzdetails1)]
[Cat(id=id1, image=img1, details=details1), Cat(id=id2, image=img2, details=details1), Cat(id=id3, image=img3, details=details1)]
Upvotes: 0
Reputation: 28392
As specified in other answers, you need a deep copy of your list. Create your newList
with:
val newList = oldList.map { it.copy() }
Even better, in your case you can do both copying and modifying at the same time:
val newList = oldList.map {
it.copy(
image = "web_" + it.image,
details = "detail_xyz" + it.details
)
}
And then you can remove onEach()
block.
Upvotes: 3