3

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?

Michael
  • 41,989
  • 11
  • 82
  • 128
Vasile Doe
  • 1,674
  • 1
  • 24
  • 40
  • 3
    Both point to the same instance of `List list`... you need to create a new instance of `List`, see how to duplicate the list [here](https://stackoverflow.com/a/56383/4391450) into a new instance – AxelH Nov 08 '17 at 10:44

5 Answers5

6

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.

Zabuzard
  • 25,064
  • 8
  • 58
  • 82
4

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);
}
Yegor Babarykin
  • 705
  • 3
  • 12
  • 3
    to elaborate: have different references to list as above. Then you use mWorkList.addAll(list); mOriginalList.addAll() to populate the data in lists – akshaya pandey Nov 08 '17 at 10:45
  • 1
    @YegorBabarykin OP must wait at least **15 minutes** to be able to accept. This ensures that others also have a chance to post good answers ([Time limit on accepting an answer](https://meta.stackexchange.com/questions/50697/time-limit-on-accepting-an-answer)). – Zabuzard Nov 08 '17 at 10:55
  • @Zabuza Thanks, i didn't know this rule – Yegor Babarykin Nov 08 '17 at 10:57
4

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.

AxelH
  • 14,325
  • 2
  • 25
  • 55
2

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);
    }
}                  
Saif Ahmad
  • 1,118
  • 1
  • 8
  • 24
1

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.

Attila Szász
  • 707
  • 4
  • 22