user15301088
user15301088

Reputation:

How to create multiple object of same data class kotlin

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

Answers (2)

Siri
Siri

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

broot
broot

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

Related Questions