当我只将对象放在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()));
答案 0 :(得分: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 :(得分:3)
您需要熟悉浅拷贝和深拷贝。
由于两个数组列表都指向堆上完全相同的对象,因此您的数组看起来像
当您修改其中一个评分圈(对象)时,由于另一个列表指向其相应索引中完全相同的内容,因此它将看到您对其他列表所做的更改。
您需要为HistoricRate类定义一个复制构造函数:
public HistoricRate(HistoricRate other){
this.data = other.data;
//copy the other instance variables here
}
然后当您将HistoricRate添加到列表中时,您可以添加
listOfRates.add(new HistoricRate( currentRate ) );
由于您使用的是“新”,因此列表将接收新对象,对其中一项的更改不会影响另一项。它看起来会像这样: