Reputation: 740
I have an ArrayList containing Arraylists, this is the code:
ArrayList<ArrayList<String>> results = new ArrayList<ArrayList<String>>();
ArrayList<String> row = new ArrayList<String>();
What I want is that the results
ArrayList contains the row
ArrayList. I thought that after adding something to an ArrayList, it would be hardcoded into that ArrayList. But it appears that the contents of the ArrayList are still related to the contents of the variable that I add to it, because when I run this code:
row.add("ROW 1 ITEM 1");
row.add("ROW 1 ITEM 2");
row.add("ROW 1 ITEM 3");
row.add("ROW 1 ITEM 4");
row.add("ROW 1 ITEM 5");
row.add("ROW 1 ITEM 6");
results.add(row);
row.clear();
log(results.toString());
The result that is logged in the console is [[]]. Is there any way I can use it this way?
Upvotes: 1
Views: 2261
Reputation: 219
This happens because Java works with references and not clones / copies by complex datatypes (non-complex types are int
, char
and similar).
In your case this means the ArrayList<String> row
gets some position in memory and is stored there.
If you now add row
straight to result
via result.add(row);
you just adding a reference (or pointer in C++) to the original position of row
in memory to ArrayList result
.
So this means if you change anything in row
it will be also changed in result
because both objects refer to the same spot in memory with is modified.
To solve this problem, you have to create a new copy each time you want to add row
a copy of it which refers to a different spot in memory and then add the copy to result.
1. Way:
create a method like this:
ArrayList<String> createCopy (ArrayList<String> orginal) {
ArrayList<String> copy = new ArrayList<String>()
for (String s:orginal) {
copy.add(s);
}
return copy;
}
2. Way:
Look up you favorite way how to create deep clones/copies of ojbects in java and use that.
Upvotes: 3
Reputation: 96
Yes, this is not working because you are removing the row ArrayList before the print. Unless you copy the contents to the results ArrayList, that data is being removed because I believe the row ArrayList is being referenced when you call that .toString() method
Upvotes: 0
Reputation: 848
You are adding reference of ArrayList row to results. Once row.clear() is called all the elements will be removed. You can log before clearing or instead of adding reference create new ArrayList and deep copy the list.
Upvotes: 1
Reputation: 1582
You can understand this in terms of how the memory is allocated to objects in Java.
Initially you have only one row
Arraylist and you are adding that ArrayList to results
Arraylist.
You need to understand that, you have instantiated/alloted memory to only one ArrayList that is row
, and results
ArrayList contains that row
object only, NOT any new object.
Hence, when you delete the row
that object is deleted.
As there is only one object in the memory, your output is empty after deletion.
Upvotes: 0
Reputation: 16224
That’s because the contents in an array list aré object’a references, so you have two references pointing to row, one is the variable row, and the other references is the first element of the array results, if you change the object using the row reference (variable), it will affect the arraylist inside the arraylist result
Upvotes: 0
Reputation: 202
Yeah, Java works with references. If you call clear
on a reference that refers to an ArrayList
, then other references referring to the exact same memory will see the same. That the ArrayList
is empty.
If you want to keep your content, then save it to a different ArrayList
instance.
Upvotes: 3