2016-06-28 11 views
0

我第一次注意到這個問題時,我只將對象放入listOfRates,然後通過複製創建inverseListOfRates。但即使使用這種方法,我也不能改變一個列表而不改變另一個列表。我有兩個包含相同對象的列表。如何更改一個列表而不更改其他列表?

我該如何解決這個問題?

List<HistoricRate> listOfRates = new ArrayList<HistoricRate>(); 
List<HistoricRate> inverseListOfRates = new ArrayList<HistoricRate>(); 

for (HistoricRate rate : rates){ 
    listOfRates.add(rate); 
    inverseListOfRates.add(rate); 
} 

inverseListOfRates.forEach(r -> r.setMid(1/r.getMid())); 

回答

5

這兩個列表引用了同一個對象。所以如果你改變第一個,第二個也會改變。

解決方案是在將對象添加到第二個列表中之前克隆該對象(將其創建爲新實例的副本)。

克隆您可以使用以下建議一個對象:

1通過拷貝構造函數:

class HistoricRate { 
    private String field; 

    public HistoricRate (HistoricRate another) { 
    this.field= another.field; // you can access 
    } 
} 

2- HistoricRate必須實現Cloneable接口

實現方法clone來複制對象。

3-使用org.apache.commons.lang.SerializationUtils如下:

for (HistoricRate rate : rates){ 
    listOfRates.add(rate); 
    inverseListOfRates.add(SerializationUtils.clone(rate)); 
} 
1

你需要熟悉淺拷貝VS深層副本。

由於兩個數組列表指向堆上完全相同的對象,你的陣列看起來像這樣enter image description here

當你修改率圓(對象)之一,因爲其他列表指向完全相同的在其相應的索引中,它會看到您對另一個列表所做的更改。

您需要定義爲HistoricRate類去拷貝構造函數:

public HistoricRate(HistoricRate other){ 
this.data = other.data; 
//copy the other instance variables here 
} 

,然後當你添加HistoricRate對你的列表,你可以添加

listOfRates.add(new HistoricRate(currentRate)); 

既然你使用'新',列表將收到新的對象,更改爲一個不會影響另一個。它會看起來像這樣:

enter image description here

相關問題