【问题标题】:I have two lists containing the same objects. How do I change one list without changing the other? [duplicate]我有两个包含相同对象的列表。如何更改一个列表而不更改另一个? [复制]
【发布时间】:2016-10-31 11:07:40
【问题描述】:

当我只将对象放在 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()));

【问题讨论】:

    标签: java list object deep-copy shallow-copy


    【解决方案1】:

    这两个列表引用同一个对象。所以如果你改变第一个,第二个也会改变。

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

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

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

    【讨论】:

      【解决方案2】:

      您需要熟悉浅拷贝与深拷贝。

      由于两个数组列表都指向堆上完全相同的对象,因此您的数组看起来像这样

      当您修改其中一个速率圈(对象)时,由于另一个列表在其相应索引中指向完全相同的事物,因此它将看到您对另一个列表所做的更改。

      您需要为 HistoricRate 类定义一个复制构造函数:

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

      然后当您将 HistoricRate 添加到您的列表中时,您可以添加

      listOfRates.add(new HistoricRate( currentRate ) );
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-29
        • 2017-01-14
        相关资源
        最近更新 更多