2015-11-05 52 views
0

我有叫人用性能的Hashmap返回引用,而不是拷貝

name 
image 
age 
amount 

一個模式,我有一個單獨的HashMap Hashmap<String,Person> globalPersonList其中包含Person對象名單。

我想從我的HashMap中檢索一個單一的對象一樣

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

我想創建一個新的Person實例,並用existingPerson性質initiallize像

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

現在我想設置量場對這個人對象。我試過像

newPerson.setAmount(100); 

但它不應該影響globalPersonList。我只需要在我的newPerson對象中獲得金額值。但是現在這個也設置在globalPersonList之內。如果我嘗試去設定金額

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

它給出我設定的金額。它是否使用對新對象的引用?我想要一個Person對象的單獨副本,以便它不會影響主散列表。

回答

6

而這是所需的行爲。你的Map'sget(...)方法將返回存儲在地圖中的對象,而不是該對象的副本。您應該爲您的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

更清潔的方法將使用[原型設計模式](https://en.wikipedia.org/wiki/Prototype_pattern) –

0

在行

Person person = new Person(); 

要創建一個新的Person對象和引用存儲在變量person

下一行

person = globalPersonList.get("key"); 

你改變了這一切參考HashMap中的Person對象之一。所以你新創建的Person現在已經不存在了,你用這個對象所做的一切現在都會影響HashMap中的一個。

你應該做的是,用HashMap中對象的值初始化新的Person對象,然後更改一個值。

0

您需要從HashMap創建Person對象的副本。這可以用一個拷貝構造函數來完成:

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值指向的同一對象。

相關問題