Home > front end >  Restore first list in Snapshot class in Java [duplicate]
Restore first list in Snapshot class in Java [duplicate]

Time:10-03

My problem is that when I call my restore() method, it gives me the original list which was initialized in the Snapshot constructor. I don't want its affecting by all changes. What must I change in Snapshot class?

import java.util.ArrayList;

public class Snapshot {
    private ArrayList<Integer> data;

    public Snapshot(ArrayList<Integer> data) {
        this.data = data;
    }


    public ArrayList<Integer> restore() {
        return this.data;
    }

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();

        list.add(1);
        list.add(2);
        Snapshot snap = new Snapshot(list);

        list.set(0, 3);
        list = snap.restore();
        System.out.println(list); //it shoul lod "[1,2]"
        
        list.add(4);
        list = snap.restore();
        System.out.println(list);//it shoul lod "[1,2]"
    }
}

CodePudding user response:

Well, an ArrayList is a mutable collection, which means it can be modified. With this.data = data, you copy the reference, so now you have two strings attached to the same balloon.

You could just create a defensive copy to just avoid this:

class Snapshot {
    private List<Integer> list;

    Snapshot(List<Integer> list) {
        this.list = new ArrayList<>(list);
    }
}

There exists an ArrayList constructor which accepts another list as argument, in order to copy the list. This is called a copy constructor.

CodePudding user response:

Currently

public ArrayList<Integer> restore() {
    return this.data;
}

this works as a getter, it returns reference to the data variable.

Also inside your constructor you are passing a reference to array and assigning it to your variable data. Now the data points to the ArrayList passed through the constructor. Any changes to this array list within Snapshot instances will be also visible to whichever class is passing ArrayList<Integer> data to the constructor. That's how Java works.

If you want to have a way to reset the data variable to be the same clone of the one passed through the constructor, you need to make a clone, operate on it, and keep the initial reference, so that the restore method can make a new copy based on that reference.

May be something like this will work:

public class Snapshot {
private ArrayList<Integer> dataReference;
private ArrayList<Integer> dataClone;

public Snapshot(ArrayList<Integer> data) {
    this.dataReference= data;
    this.dataClone = new ArrayList<>(data);
}


public ArrayList<Integer> restore() {
    return this.dataClone = new ArrayList<>(dataReference);
}

I'm a bit rusty with Java but try it out. You can look out for further reading on this topic like here or find similar https://howtodoinjava.com/java/collections/arraylist/arraylist-clone-deep-copy/

  • Related