我有两个包含相同对象的列表。如何更改其中一个列表而不影响另一个列表?

3
我最初注意到这个问题是当我只把对象放在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()));
2个回答

6

这两个列表引用的是同一个对象。因此,如果您更改了第一个对象,第二个对象也会发生变化。

解决方法是在将其添加到第二个列表之前克隆该对象(将其复制到新实例中)。

要克隆对象,您可以使用以下建议之一:

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));
}

4

你需要熟悉浅拷贝和深拷贝。

由于数组列表都指向堆上的确切对象,因此您的数组看起来像这样 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 ) );

由于您正在使用“new”,因此列表将接收新对象,对其中一个对象的更改不会影响另一个对象。它看起来会像这样:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接