1

In my main class, I loop through 120 files. For each file I create a 2d array of the data contained within.

My 2d Array is "fullData" of type List<List<String>>. ParserIPAM is an inherited class and i declare fullData in its super class.

This is my code within main:

for(String filename : filefetcher.getFiles()){
            System.out.println("file to parse: "+ filename);
            ipam = new ParserIPAM(filename);
            i=0;
            boolean flag = true;
            System.out.println("------------------------------------------");
            for(List<String> row : ipam.getSqlData()){
                //queries.insertVars(row);
                //System.out.println(row);
            }
            //System.out.println(i);
            ipam.clearSqlData();
        }

And here is my code where I fill the 2d Array:

public ParserIPAM(String filename){
        super(filename);
        try {
            Parse(filename);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        SpecialOperations(fullData);
        //System.out.println("+++++++++++++++++++++++++++++++++++"+ls2d.size());
    }

    @Override
    void Parse(String filename) throws FileNotFoundException{
        fullData.clear();
        FileReader input = new FileReader(filename);
        ArrayList<String> Raw = new ArrayList<String>();
        BufferedReader bufRead = new BufferedReader(input);
        Scanner bufferinput = new Scanner(bufRead);
        String nextline = bufferinput.nextLine();
        int i = 0;
        while(bufferinput.hasNext()){
            Raw.clear();
            nextline = bufferinput.nextLine();

            for(String cell: nextline.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)")){
                Raw.add(cell);              
                //System.out.print(i+"    "+cell);  ////// THIS PRINTS CORRECT DATA         
            }
            i++;
            //System.out.println(i + "    " + Raw); ////THIS PRINTS CORRECT DATA
            fullData.add(Raw);

        }

        for(List<String> sub: fullData){

                //System.out.println(sub); ///THIS DOES NOT PRINT CORRECTLY

        }

    }

Edit: ParserIPAM is an inherited class. Here is the complete code for the super class:

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

public abstract class Parser {
    protected static String filename;
    //private List<List<String>> dataArray = new ArrayList<ArrayList<String>()>();
    protected List<List<String>> fullData = new ArrayList<List<String>>();
    public Parser(String filename){
        //this.filename = filename;
    }
    //Parse will only parse file and put raw data into a 2d ArrayList.
    abstract void Parse(String filename) throws FileNotFoundException;
    //SpecialOperations will add additional data to raw data for table insertions.
    abstract void SpecialOperations(List<List<String>> data);


}

When I print everything out in the last System.out it prints the correct number of elements (256) but it always prints out the last line of the file 256 times in a row. I'm not exactly sure if I'm filling the array incorrectly or if I'm printing it incorrectly. Either way its wrong and I can't seem to figure it out.

I know there is probably a better way to do this than with an ArrayList, but that's not affecting the issue I'm having.

Ryan Brady
  • 147
  • 1
  • 12

2 Answers2

5

You only create one ArrayList instance (and clear it in your loop), so you only have one reference added (just many times). For Java 7 and above, the easiest solution I can think of is to use new ArrayList<>() diamond operator instead -

// Raw.clear();
Raw = new ArrayList<>();

for Java 6 and 5,

// Raw.clear();
Raw = new ArrayList<String>();

Similarly, you could also use this instead -

// fullData.add(Raw);
fullData.add(new ArrayList<>(Raw)); // <-- copies Raw
Community
  • 1
  • 1
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • This did it. I'm kind of confused why i have to re initialize every time though. Thanks for the fix though. – Ryan Brady Jun 24 '14 at 16:36
  • @RyanBrady Think of the List like your wallet. If you empty your wallet and then put it in your pocket. Where are your money and credit cards? It's necessary for each List to act like a separate wallet, because if you only use one - it only contains one wallet worth of stuff. – Elliott Frisch Jun 24 '14 at 16:38
  • @Ryan It's because Java passes by reference. When you keep reusing the same object, you only have one reference. It's like the wallet analogy - you stored cash in the wallet and then threw the cash out to store the next set of cash in the same wallet. Instead you should be getting multiple wallets to store multiple sets of cash (this is what you achieve by reinitialization). Anyway this is a common misunderstanding by beginners and causes a lot of bugs. Read up on "pass by reference" and "pass by value" in relation to Java. – ADTC Jun 24 '14 at 17:19
3

Try putting the instantiation of Raw inside the While loop

while(bufferinput.hasNext()){

        ArrayList<String> Raw = new ArrayList<String>();
        Raw.clear();
        nextline = bufferinput.nextLine();

        for(String cell: nextline.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)")){
            Raw.add(cell);              
            //System.out.print(i+"    "+cell);  ////// THIS PRINTS CORRECT DATA         
        }
        i++;
        //System.out.println(i + "    " + Raw); ////THIS PRINTS CORRECT DATA
        fullData.add(Raw);

    }
Minutiae
  • 151
  • 6