3

I have one model called Person with properties

name
image
age
amount

and I have a singleton hashmap Hashmap<String,Person> globalPersonList which contains list of person objects.

I am trying to retrieve one single object from my hashmap like

Person existingPerson = globalPersonList.get("key");

I want to create a new Person instance and initiallize with existingPerson properties like

Person person = new Person();
person  =  globalPersonList.get("key");

Now I want to set amount field to this person object. I tried like

newPerson.setAmount(100); 

but it shouldn't affect globalPersonList. I want amount value only in my newPerson object. But right now this is set in globalPersonList also. after setting amount if I try to

globalPersonList.get("key").getAmount()

it is giving the amount that I set. Is it using the reference to new object? I want a seperate copy of Person object so that it won't affect main hashmap.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
dev
  • 1,085
  • 4
  • 19
  • 26

3 Answers3

10

And this is the desired behavior. Your Map's get(...) method will return the object that is stored inside your map, not a copy of that object. You should use a copy constructor for your Person.

public Person(Person sourcePerson) {
    //copy all field values (you didn't write what are your fields so I might not be 100% accurate here)
    this.name = sourcePerson.name;
    this.image = sourcePerson.image; //I don't know what type of data is stored in image so I'll just assume it's a String url path to an image
    this.age = sourcePerson.age;
    this.amount = sourcePerson.amount;
}

and then:

Person person = new Person(globalPersonList.get("key"));
Bartek Lipinski
  • 30,698
  • 10
  • 94
  • 132
  • A cleaner approach will be using the [Prototype design pattern](https://en.wikipedia.org/wiki/Prototype_pattern) – Ido Sorozon Jan 21 '18 at 19:55
  • Any idea on why `map.get(key) = newValue` doesn't change the value for the given `key` if map.get(key) actually returns the same object? I guess map.get(key) just returns the reference to that object. Does assigning to newValue just changes the object that the referencing is now pointing to, instead of modifying the actual value? – asn Aug 04 '23 at 20:56
  • @asn `map.get(key)` is for getting the `value` for a particular `key` in the `map`. if you want to update something in the `map` you should use `map.put(key, newValue)` – Bartek Lipinski Aug 11 '23 at 11:12
  • @BartekLipinski Yeah I understand that map.put does the job. But, the question is why map.get(key) - newvalue won't work? – asn Aug 11 '23 at 11:35
  • @asn I really don't understand what `map.get(key) = newValue` is supposed to do. `get` is strictly for taking values from the `map`. It cannot do anything to update values in it. – Bartek Lipinski Aug 11 '23 at 11:45
  • @asn It's because hashmap uses an internal array and the location of put() depends on the key content. So if you change key it puts it entirely somewhere else in that array. – LegendLength Aug 23 '23 at 03:15
0

In the line

Person person = new Person();

you are creating a new Person object and store the reference in the variable person.

In the next line

person  =  globalPersonList.get("key");

you are changing that reference to the one of the Person object in the HashMap. So your newly created Person is now gone and everything you do with that object now affects the one from the HashMap.

What you should do instead, is initialize the new Person object with the values of the one from object in the HashMap and then change a value.

Hendrik Simon
  • 231
  • 2
  • 10
0

You need to create a copy of the Person object from the HashMap. This can be done with a copy constructor:

public Person(Person person){
   // Setup with the same values as the passed in Person.
}

Then you would instantiate a new Person using this constructor as follows;

Person newPerson = new Person(globalPersonList.get("key"));

The reason for this is that when you call globalPersonList.get("key") you are getting a reference to the object that is sat on the heap. Then when you write newPerson = globalPersonList.get("key"); you are actually saying you want the newPerson reference to point at the same object that globalPersonList.get("key") points to.

Therefore if you change a value on newPerson you are actually changing the same object that the HashMap value points to.

kstandell
  • 775
  • 6
  • 16