Hello,

Trying to clone an ArrayList with all variables. As a result, I change the values ​​of degrees in a new sheet. And automatically change the data in the old sheet. Although I use an example in which the data of the old sheet should remain unchanged.

 ArrayList<HeatSensor> celsius = new ArrayList<HeatSensor>(); ArrayList<HeatSensor> fareng = (ArrayList<HeatSensor>) celsius.clone(); for(HeatSensor h: fareng) { double far = h.getCelsius(); far = 9*far/5 + 32; h.setCelsius(far); System.out.println(h.toString()); } 

To make it clearer, this is what is displayed on the screen:

 ================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 

There is also another question regarding the same program. find the maximum value in ArrayList

  • OK. And I will do it - Alex

2 answers 2

The clone method is defined in ArrayList as copying links of elements.

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

Thus, the elements are equal to the reference celsius.get(i) == fareng.get(i) for any i , and if you change an item in one list, you change it in another list.

To solve your question, you need to use deep copying , that is, make additional copies of the elements themselves.

 for (HeatSensor h : celsius) { fareng.add(h.clone()); } 

PS in the development is not recommended to use the clone method. It is considered a bad design in the app. You should use copying through the constructor.

 List<HeatSensor> fareng = new ArrayList<>(celsius.size()); for (HeatSensor h : celsius) { fareng.add(new HeatSensor(h)); } 

And the designer himself:

 public HeatSensor(HeatSensor another) { this.celsius = another.celsius; // и так далее по аналогии } 
  • Thanks for the detailed explanation! - Alex

Implement the clone() method in the HeatSensor class and clone the lists as follows:

 ArrayList<HeatSensor> celsius = new ArrayList<>(); ArrayList<HeatSensor> fareng = new ArrayList<>(); for (HeatSensor h : celsius) fareng.add(h.clone()); 

Your option does not work, because lists are cloned, but the objects remain the same.

  • Thank you very much! - Alex