B4J Question strange issue with map value changing

Nokia

Active Member
Licensed User
Longtime User
I have a map called ResultsMap on my main app main window. So I have a class (clsTest) that opens another window called test.. and I'm passing the ResultsMap through the Test.Initialize(ResultsMap) sub.

on sub Initialize(rMap as object)

I load the Global variable LoadedMap as Map
LoadedMap = rMap

So the issue is if I change/update items in the LoadedMap for testing purpose in the test window.. it changes the ResultsMap on the main app/window.

How do I keep it from changing items on ResultsMap on main windows if I change it on the test window?
 
Solution
Code with GetKetAt = broken code.
You will need to copy the map:
B4X:
Public Sub CopyMap(m As Map) As Map
 Dim NewMap As Map
 NewMap.Initialize
 For Each Key As Object In m.Keys
  NewMap.Put(Key, m.Get(Key))
 Next
 Return NewMap
End Sub

Nokia

Active Member
Licensed User
Longtime User
so instead of passing the map.. I copied the map and it seems to work.. not sure if this is proper or a better way of doing.. any suggestion welcome..

B4X:
        LoadedMap.Initialize
        For kv = 0 To rMap.Size - 1
            LoadedMap.Put(rMap.GetKeyAt(kv), rMap.GetValueAt(kv))
        Next
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
strange issue with map value changing
For clarification - this is expected behaviour. A Map is a non-primitive object. This means that a Map variable does not contain the actual Map object (like a primitive type would do) but contains the address of the Map in memory. So when you pass the Map value you are passing its address and both variables point to the same object.You can use this to your benefit on many occasions when you do want to modify a Map or other non-primitive like an Array, but occasionally it can catch you out - like in this instance.
 
Upvote 0

Nokia

Active Member
Licensed User
Longtime User
Code with GetKetAt = broken code.
You will need to copy the map:
B4X:
Public Sub CopyMap(m As Map) As Map
 Dim NewMap As Map
 NewMap.Initialize
 For Each Key As Object In m.Keys
  NewMap.Put(Key, m.Get(Key))
 Next
 Return NewMap
End Sub

makes sense..
 
Upvote 0
Top