Scotch
Scotch

Reputation: 3226

ArrayList.clear() in a two dimensional ArrayList(ArrayList of ArrayLists)

So I'm having some issues with adding ArrayLists to my ArrayList. Think of this as a table.

Here's some example code:

 ArrayList<String> currentRow = new ArrayList<String>(); 

  while ((myLine = myBuffered.readLine()) != null) {

    if(rowCount == 0) {// get Column names  since it's the first row

        String[] mySplits;
        mySplits = myLine.split(","); //split the first row

        for(int i = 0;i<mySplits.length;++i){ //add each element of the splits array to the myColumns ArrayList
            myTable.myColumns.add(mySplits[i]);
            myTable.numColumns++;
            }
        }
    else{ //rowCount is not zero, so this is data, not column names.
    String[] mySplits = myLine.split(","); //split the line
    for(int i = 0; i<mySplits.length;++i){

    currentRow.add(mySplits[i]); //add each element to the row Arraylist

    }
    myTable.myRows.add(currentRow);//add the row arrayList to the myRows ArrayList
    currentRow.clear(); //clear the row since it's already added
        //the problem lies here *****************
     }
    rowCount++;//increment rowCount
    }
 }

The problem is when I don't call currentRow.clear() to clear the contents of the ArrayList that I'm using in each iteration (to put into my ArrayList of ArrayList), with each iteration, I get that row PLUS every other row.

But when I do call currentRow.clear() after I add currentRow to my arrayList<ArrayList<String>, it actually clears the data that I added to the master arrayList as well as the currentRow object.... and I just want the currentRow ArrayList empty but not the ArrayList that I just added to my ArrayList (Mytable.MyRows[currentRow]).

Can anyone explain what's going on here?

Upvotes: 2

Views: 2495

Answers (2)

Chris Hayes
Chris Hayes

Reputation: 12030

The problem lies here:

myTable.myRows.add(currentRow);

You add the ArrayList currentRow to the "master" list here. Note that under Java semantics, you are adding a reference to the currentRow variable.

On the next line, you immediately clear currentRow:

currentRow.clear()

Hence, when you try to use it later, the "master" list looks up that reference from before and finds that while there is an ArrayList object, it contains no Strings within it.

What you really want to do is start over with a new ArrayList, so replace the previous line with this:

currentRow = new ArrayList<String>();

Then the old object is still referred to by the "master" list (so it will not be garbage collected) and when it is accessed later, its contents will not have been cleared.

Upvotes: 4

Louis Wasserman
Louis Wasserman

Reputation: 198043

Don't clear the current row, instead create a completely fresh ArrayList for each row, inside your outer loop.

When you add currentRow to the list, you're adding a reference to the list, not a copy that will continue to exist independently.

Upvotes: 1

Related Questions