I have two lists containing the same objects. How do I change one list without changing the other? [duplicate]

自作多情 提交于 2020-12-25 18:17:20

问题


I first noticed this problem when I only put the objects in listOfRates and then created inverseListOfRates by copying it. But even using this method, I can't alter one list without altering the other.

How do I solve this issue?

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

回答1:


The two lists are referencing the same object. So if you change the first, the second will change also.

The solution is to clone the object (Creating a copy of it into a new instance) before adding it into the second list.

To clone the object you can either use one of the following suggestions:

1- A constructor by copy :

class HistoricRate {
  private String field;

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

2- HistoricRate must implement Cloneable interface

Implement the method clone to copy the object.

3- Use org.apache.commons.lang.SerializationUtils as below :

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



回答2:


You need to familiarize yourself with shallow copies vs deep copies.

Since both array lists point to the exact same objects on the heap, your array looks like this

When you modify one of the rate circles (objects), since the other list is pointing to the exact same thing in its corresponding index, it will see the changes you made with the other list.

You need to define a copy constructor for the HistoricRate class that goes:

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

and then when you add the HistoricRate's to your lists, you can add

listOfRates.add(new HistoricRate( currentRate ) );

Since you're using 'new', the list will receive new objects and changes to one won't affect the other. It'll look like this instead:



来源:https://stackoverflow.com/questions/38087775/i-have-two-lists-containing-the-same-objects-how-do-i-change-one-list-without-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!