Conner Dassen
Conner Dassen

Reputation: 740

Clearing something after adding it do an ArrayList clears the ArrayList too

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

Answers (6)

ProfBits
ProfBits

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

mapage2
mapage2

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

uhs
uhs

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

pro_cheats
pro_cheats

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

developer_hatch
developer_hatch

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

T&#246;rpetestű
T&#246;rpetestű

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

Related Questions