Страницы

Поиск по вопросам

понедельник, 10 февраля 2020 г.

ArrayList не клонируется

#java #arraylist


Здравствуйте, 

Пытаюсь клонировать ArrayList со всеми переменными. В итоге изменяю значения градусов
в новом листе. И автоматически изменяются данные в старом листе. Хотя использую пример,
в котором данные старого листа должны остаться неизменными.

ArrayList celsius = new ArrayList();
ArrayList fareng = (ArrayList) celsius.clone();

for(HeatSensor h: fareng) { 
    double far = h.getCelsius();
    far = 9*far/5 + 32;

    h.setCelsius(far);

    System.out.println(h.toString());
}


Чтобы было понятнее, вот что выводится на экран:

================celsius============================  
Heat : 70.0, 1/02/2017  
Heat : 30.0, 1/02/2017  
Heat : 35.0, 3/02/2017  

================fahrenheit==========================  
Heat : 158.0, 1/02/2017  
Heat : 86.0, 1/02/2017  
Heat : 95.0, 3/02/2017  

================celsius============================    
Heat : 158.0, 1/02/2017   
Heat : 86.0, 1/02/2017    
Heat : 95.0, 3/02/2017    


Так же имеется другой вопрос относительно этой же программы.
найти максимальное значение в ArrayList
    


Ответы

Ответ 1



Метод clone определен в ArrayList как копирование ссылок элементов. public Object clone() { try { ArrayList v = (ArrayList) super.clone(); v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(e); } } Таким образом, элементы равны с точностью до ссылки celsius.get(i) == fareng.get(i) для любого i, и при изменении элемента в одном списке вы измените его же в другом списке. Для решения вашего вопроса нужно воспользоваться глубоким копированием, то есть сделать дополнительно и копии самих элементов. for (HeatSensor h : celsius) { fareng.add(h.clone()); } P.S. в разработке не рекомендуется использовать метод clone. Он считается плохим дизайном в приложении. Вам стоит воспользоваться копированием через конструктор. List fareng = new ArrayList<>(celsius.size()); for (HeatSensor h : celsius) { fareng.add(new HeatSensor(h)); } И сам конструктор: public HeatSensor(HeatSensor another) { this.celsius = another.celsius; // и так далее по аналогии }

Ответ 2



Реализуйте метод clone() в классе HeatSensor и клонируйте списки следующим образом: ArrayList celsius = new ArrayList<>(); ArrayList fareng = new ArrayList<>(); for (HeatSensor h : celsius) fareng.add(h.clone()); Ваш вариант не работает, т.к. клонируются списки, но объекты остаются одни и те же.

Комментариев нет:

Отправить комментарий