Appalachian Math Appalachian Math - 4 months ago 19
Java Question

List<List<Integer>> ArrayList initialization does not work with new operator Java

I have been struggling on this problem for two days. This problem comes from some problem I am doing. Basically, when I use

List<List<Integer>> temp = new ArrayList<>(result);


to create a new ArrayList copy of result, the result will change when I try to change temp within an advanced for loop. For example,

List<List<Integer>> result = new ArrayList<>();
result.add(new ArrayList<>());
List<List<Integer>> temp = new ArrayList<>(result);
int j = 0;
for (List<Integer> list: temp) {
list.add(x[j]);
j ++;
}


I did nothing to the result inside the loop but the result ends up with [[1]], which is the same as temp.

Why is this happening? Thanks a lot.

Update: thank everybody for answering my question. I learn the shallow copy was the reason. However, I still run into a similar problem. The result is updated while I try to change the temp in the following code:

List<List<Integer>> result = new ArrayList<>();
result.add(new ArrayList<>());
List<List<Integer>> temp = new ArrayList<>();
for (List<Integer> list: result) {
list.add(10000);
temp.add(new ArrayList(list));
}


I do not know why the result turns out to be [[10000]] as well as the temp. Is there anything wrong with the add method like temp.add(new ArrayList(list))?

Answer

This is happening because the List<List<Integer>> temp = new ArrayList<>(result); statement copies only the top-level list. It will be the new list that contains references to the original items (aka sublists) from the original result.

You can fix this with a deep copy:

List<List<Integer>> temp = new ArrayList<>(); // empty list
for (List<Integer> sublist : result) {
    temp.add(new ArrayList<Integer>(result)); // copying a sublist and adding that
}