Vasile Doe
Vasile Doe

Reputation: 1754

Java list changed when update another one

Supposing we have:

public class Test {

    private List<String> mWorkList;
    private List<String> mOriginalList;

    public Test(List<String> list) {
        mWorkList = list;
        mOriginalList = list;
    }

    public void updateData(List<String> newList) {
        mWorkList.clear();
        mWorkList.addAll(newList);
    }
}

I want to change only mWorkList but mOriginalList is changed too when I call updateData(List<String>). So how should I do it to keep mOriginalList as initially assigned in constructor?

Upvotes: 3

Views: 4565

Answers (5)

Yegor Babarykin
Yegor Babarykin

Reputation: 705

You should create new List object in function Test, because all your lists refer to one variable

public Test(List<String> list) {
    mWorkList = new ArrayList<>(list);
    mOriginalList = new ArrayList<>(list);
}

Upvotes: 4

AxelH
AxelH

Reputation: 14572

You are setting both list with the same instance reference with

mWorkList = list;
mOriginalList = list;

You need to create a new instance for mOriginalList by duplicating the list. This can be done with one of the constructor of ArrayList(Collection).

mOriginalList = new ArrayList<>(list);

Please note that the instances in both list are the same, so if you update an instance in list, it will be changed in mOriginalList. If you want to break that link too, you will need to clone the list and his content.

Upvotes: 4

Saif Ahmad
Saif Ahmad

Reputation: 1171

Whenever you assign a object to another object only the reference is assigned (Shallow copy). You should call copy constructor to make a deep copy.

public class Test {

    private List<String> mWorkList;
    private List<String> mOriginalList;


    public Test(List<String> list) {
        mWorkList = new ArrayList<>(list);
        mOriginalList = new ArrayList<>(list);
    }

    public void updateData(List<String> newList) {
        mWorkList.clear();
        mWorkList.addAll(newList);
    }
}                  

Upvotes: 2

Zabuzard
Zabuzard

Reputation: 25903

In Java you pass variables by their reference. This means that whenever you do an assignment like mWorkList = list the variable mWorkList will point to the same place in memory where list is currently pointing. If you do mOriginalList = list, then mOriginalList will also point to that position. I.e. all three lists refer the same object at that point.


If you want independent lists you need to copy all values from the list to a new list like this:

List<String> myList = new ArrayList<>(otherList);

This constructor of ArrayList automatically adds all values from the other list, here is its documentation.


Your code could then look like:

public Test(List<String> list) {
    mWorkList = new ArrayList<>(list);
    mOriginalList = new ArrayList<>(list);
}

Or if you don't intent to change mOriginalList you could also leave it as mOriginalList = list. But then bear in mind that if the user makes changes to list (which comes from outside of your class) they will also be reflected in your mOriginalList which could easily lead to nasty bugs.

Upvotes: 6

Attila Sz&#225;sz
Attila Sz&#225;sz

Reputation: 747

In java every variable is a reference, so in this case it's normal that both variable changes if you change one of them.

To keep a copy you have to create a new object and clone the original one.

Upvotes: 1

Related Questions