B4J Question Basic question about maps

maps do not seem to work the way i expect them too. i use the example below to explain my misunderstanding. i would expect the log output to display both empinfo. but instead the log output looks like this.
Waiting for debugger to connect...
Program started.
(MyMap) {emp1=[IsInitialized=false, LastName=smith, FirstName=john
, Age=20], emp2=[IsInitialized=false, LastName=smith, FirstName=john
, Age=20]}

it seems to me that what i "put" into the map is a pointer to empinfo instead of a copy of empinfo. is that correct ?? how should i go about putting a "copy" of empinfo into the map ??
here's the code

Sub Process_Globals
Private fx As JFX
Private MainForm As Form
Private xui As XUI
Private Button1 As B4XView
Private MyMap As Map
Type EmpInfos(LastName As String,FirstName As String,Age As Int)
End Sub

Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.RootPane.LoadLayout("Layout1")
MainForm.Show
MyMap.Initialize
Dim empinfo As EmpInfos

empinfo.LastName = "webb"
empinfo.FirstName = "mike"
empinfo.Age = 39
MyMap.Put("emp1",empinfo)

empinfo.LastName = "smith"
empinfo.FirstName = "john"
empinfo.Age = 20
MyMap.Put("emp2",empinfo)

Log(MyMap)
End Sub

Sub Button1_Click
xui.MsgboxAsync("Hello World!", "B4X")
End Sub
 

Quandalle

Member
Licensed User
B4X:
...
MyMap.Initialize
Dim empinfo1 As EmpInfos
Dim empinfo2 As EmpInfos

empinfo1.initialize
empinfo1.LastName = "webb"
empinfo1.FirstName = "mike"
empinfo1.Age = 39
MyMap.Put("emp1",empinfo1)

empinfo2.initialize
empinfo2.LastName = "smith"
empinfo2.FirstName = "john"
empinfo2.Age = 20
MyMap.Put("emp2",empinfo2)
...

or inside a loop
B4X:
...

    For i = 1 To 4
        Dim empinfo As EmpInfos
        empinfo.Initialize
        empinfo.LastName = "webb" & i
        empinfo.FirstName = "mike" & i
        empinfo.Age = 39 + i
        MyMap.Put("emp"&i,empinfo)
    Next
...
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
it seems to me that what i "put" into the map is a pointer to empinfo instead of a copy of empinfo. is that correct
Yes. Technically it is a 'reference' (pointer) to the actual object. Primitive numeric values are passed as is, complex objects are passed as references to the actual object. Strings are also passed as references but behave like primitive values as you can't change the contents of a string but have to create another with the changed contents. This means that the internal values of Lists, Arrays, Maps and user defined types can be changed by using the passed reference.

If you need to make a copy of a referenced object Dim a new variable, Initialize it and copy the elements.
 
Upvote 0
inside a loop would be the way i want to go, like this:

For i = 1 To 4
Dim empinfo As EmpInfos
empinfo.Initialize
empinfo.LastName = "webb" & i
empinfo.FirstName = "mike" & i
empinfo.Age = 39 + i
MyMap.Put("emp"&i,empinfo)
Next

i didn't try it in a loop, i redcared the variable and reinitialize it like so:

Dim EmpInfo As EmpInfos
EmpInfo.LastName = "webb"
EmpInfo.FirstName = "mike"
EmpInfo.Age = 39
MyMap.Put("emp1",EmpInfo)

Dim EnInfo As EmpInfos
EnInfo.Initialize
EmpInfo.LastName = "smith"
EmpInfo.FirstName = "john"
EmpInfo.Age = 20
MyMap.Put("emp2",EmpInfo)

still didn't work. has to be in a loop ?? why ?? i know how to do what i want, but i don't understand it. why is being in a loop required ? sorry for being so dense.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Or simpler, without having to write Sub CreateEmpInfos

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    For i = 1 To 4
        MyMap.Put("emp"&i, CreateEmpInfos("webb" & i, "mike" & i, 39 + i))
    Next   
End Sub

'This routine is created automatically when you hover over the Type statement name
Public Sub CreateEmpInfos (LastName As String, FirstName As String, Age As Int) As EmpInfos
    Dim t1 As EmpInfos
    t1.Initialize
    t1.LastName = LastName
    t1.FirstName = FirstName
    t1.Age = Age
    Return t1
End
 
Upvote 0
Top