У меня есть два списка с одинаковыми объектами. Как изменить один список, не изменяя другой?

Я впервые заметил эту проблему, когда поместил объекты только в 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()));

person user101    schedule 28.06.2016    source источник


Ответы (2)


Два списка ссылаются на один и тот же объект. Итак, если вы измените первое, второе тоже изменится.

Решение состоит в том, чтобы клонировать объект (создать его копию в новом экземпляре) перед добавлением его во второй список.

Чтобы клонировать объект, вы можете использовать одно из следующих предложений:

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));
}
person Radouane ROUFID    schedule 28.06.2016

Вам нужно познакомиться с мелкими копиями и глубокими копиями.

Поскольку оба списка массивов указывают на одни и те же объекты в куче, ваш массив выглядит следующим образом: введите описание изображения здесь

Когда вы изменяете один из кружков (объектов) ставок, поскольку другой список указывает на то же самое в соответствующем индексе, он увидит изменения, внесенные вами с другим списком.

Вам необходимо определить конструктор копирования для класса HistoricRate, который выглядит следующим образом:

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

а затем, когда вы добавляете HistoricRate в свои списки, вы можете добавить

listOfRates.add(new HistoricRate( currentRate ) );

Поскольку вы используете «новый», в список будут попадать новые объекты, и изменения одного не повлияют на другой. Вместо этого это будет выглядеть так:

введите описание изображения здесь

person Solace    schedule 28.06.2016