Hashmap返回引用而不是副本

问题描述 投票:0回答:3

我有一个名为Person with properties的模型

name
image
age
amount

我有一个单独的hashmap Hashmap<String,Person> globalPersonList,其中包含person对象列表。

我试图从我的hashmap中检索一个单个对象

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

我想创建一个新的Person实例并使用existingPerson属性初始化

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

现在我想将amount字段设置为此person对象。我尝试过

newPerson.setAmount(100); 

但它不应该影响globalPersonList。我只想在我的newPerson对象中使用金额值。但是现在这也是在globalPersonList中设定的。设定金额后,如果我尝试

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

它给出了我设定的金额。它是否使用对新对象的引用?我想要一个Person对象的单独副本,这样它就不会影响主hashmap。

java hashmap
3个回答
7
投票

这是理想的行为。您的Map's get(...)方法将返回存储在地图内的对象,而不是该对象的副本。您应该为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;
}

然后:

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

0
投票

在线

Person person = new Person();

您正在创建一个新的Person对象并将该引用存储在变量person中。

在下一行

person  =  globalPersonList.get("key");

您正在更改对HashMap中Person对象的引用。因此,您新创建的Person现在已经消失,您使用该对象所做的一切现在都会影响HashMap中的那个。

你应该做的是使用HashMap中对象的值初始化新的Person对象,然后更改一个值。


0
投票

您需要从Person创建HashMap对象的副本。这可以使用复制构造函数完成:

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

然后你将使用这个构造函数实例化一个新的Person,如下所示;

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

这样做的原因是当你调用globalPersonList.get("key")时,你会得到对堆上的对象的引用。然后,当你写newPerson = globalPersonList.get("key");时,你实际上是在说你希望newPerson引用指向globalPersonList.get("key")指向的同一个对象。

因此,如果更改newPerson上的值,则实际上正在更改HashMap值指向的同一对象。

© www.soinside.com 2019 - 2024. All rights reserved.