0

Found the answer -> dataclass copy with field ArrayList - change the ArrayList of the copied class changes the original

I have this wired bug. I have an array list of size 3. The third item is a duplicate of the second item in the list. I differentiate them based on their position on the list. The problem is that when I do a for loop to change the properties of the item at index 1 the item at index 2 reflects the same change.

What I've tried so far. ...

  1. I have confirmed that the list is being changed at only one spot in the app.
  2. Added more fields to differentiate the duplicate items.
  3. Set if statements to make sure that I am only changing the specific item.

What I think the solution is.

My assumption is that since the items at index 1 & 2 have a coupled relationship since they are duplicates of each other. (even with differentiating factors) I don't know what this relationship is.

My code snippet.

    private fun testing(selectedNormalModifier: ToppingModel) {
    var modIndex = -1
    selectedNormalModifier.parentPosition = selectedModifierPosition
    selectedNormalModifier.localToppingName = modifierGroupModel!!.itemModifierGroups[selectedModifierPosition].itemLocalTitle.toString()

    val itemToEdit = modifierGroupModel!!.itemModifierGroups[selectedModifierPosition]
    for (i in itemToEdit.modifierGroups.modifiers.indices) {
        val mod = itemToEdit.modifierGroups.modifiers[i]
        if (mod.title == selectedNormalModifier.toppingName) {
            modIndex = i
        }
    }

    itemToEdit.modifierGroups.modifiers[modIndex].isItemSelected = true

    mSelectedNormalModifiers.add(selectedNormalModifier)

    Log.e(TAG, "how many times did we get here $modifierGroupModel")
}

As you can see I am being very specific on the item that I want to edit. Regardless of this, the item at index 2 also gets edited and vice versa.

This is how I duplicate the items

                    for (i in modifierGroupModel!!.itemModifierGroups.indices) {
                    val item = modifierGroupModel!!.itemModifierGroups[i]
                    // only do this if the display count is greater than one
                    if (item.modifierGroups.displayCount.toInt() > 1) {
                        for(i in 0 until  item.modifierGroups.displayCount.toInt()){
                            val localIndex = i + 1
                            item.itemIndex = localIndex
                            item.itemLocalTitle = getNumberOfName(localIndex) + " " + item.modifierGroups.modifierGroupTitle
                            tempItemModifierGroupModel.add(if (i > 0) item.copy() else item)
                        }
                    } else {
                        item.itemIndex = i
                        tempItemModifierGroupModel.add(item)
                    }
                }


                val newModidiferGroupModel = ModifierGroupsModel(
                        itemID = modifierGroupModel!!.itemID,
                        itemName = modifierGroupModel!!.itemName,
                        itemModifierGroups = ArrayList(tempItemModifierGroupModel.toMutableList())
                )


                modifierGroupModel = newModidiferGroupModel

The JSON object looks like this

   "item"   {
      "nested list"[
         "isSelected": "false"
      ]
   },
   "item"   {
      "nested list"[
         "isSelected": "false" // when i change this to true
      ]
   },
   "item"   {
      "nested list"[
         "isSelected": "false" // this one changes as well
      ]
   }
]```






Aleckson Nyamwaya
  • 1,233
  • 2
  • 9
  • 12

2 Answers2

1

I'm guessing because you didn't show your Item data class but it looks like you are not editing the item in your list, but rather some indirectly referenced object. See this line:

itemToEdit.modifierGroups.modifiers[modIndex].isItemSelected = true

itemToEdit is not getting modified. Some indirectly referenced object in a collection called modifiers is what you're modifying.

When you copy an Item, it only copies all the property values. For a non-primitive property, the value is a reference to specific instance of a class. It does not perform a "deep copy". So your items at index 1 and 2 are different objects, but they reference the same instance of whatever is in the modifierGroups property.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • 1. I think I confused you with my variable names...I want to edit the ` modifier` at the given index. and that is happening. `itemToEdit` should really be `mItem`. So the real problem here is that even when I explicitly stay I want to edit the item at `position 1` it also edits item at `position 2`. ..check the code snippet to see what `itemToEdit` is...I updated the code snippet 2. `if (obj1 === obj2)` returns `false` so i am NOT refering to the exact same instance – Aleckson Nyamwaya Mar 04 '20 at 21:07
0

I found the answer. ---> this other Stack Overflow question answered it. dataclass copy with field ArrayList - change the ArrayList of the copied class changes the original

The user @Andrey_yog

Aleckson Nyamwaya
  • 1,233
  • 2
  • 9
  • 12