Home > Software engineering >  ArrayList contents Out of Scope, and deleted, after a While Loop in Java
ArrayList contents Out of Scope, and deleted, after a While Loop in Java

Time:01-19

I'm attempting to save a list of lists to an ArrayList using a while loop which is looping over the lines in a scanner. The scanner is reading a 12 line text file of binary. The list of list (ArrayList) is successfully created, but as soon as the while loop terminates the variable ArrayList is empty and an empty list of lists is returned. I also tested the code by declaring a counter at the same time I declare the list of lists and the counter is incremented in the while loop and retains the data after the loop.

I'm still very new to coding! Thank you in advance.

public static void main(String[] args) throws Exception{
        
        
        try { 
            readFile();
            data = dataPrep();
        }
        catch (Exception e) {
            e.printStackTrace ();
        }
        
    }
    
    public static void readFile() throws FileNotFoundException {
 
        try {
            File inputtxt = new File("test.txt");
            scanner = new Scanner(inputtxt);
        }
    
        catch (FileNotFoundException error) {
            System.out.println(error);
        }
    }



public static ArrayList<ArrayList> dataPrep(){
        ArrayList<ArrayList> allBinaryNumbers = new ArrayList<ArrayList>();
        ArrayList<Integer> singleBinaryNumber = new ArrayList<Integer>();  
        
        int counter = 0;
      
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            char[] charLine = line.toCharArray();
            
            for (char numb : charLine){
                singleBinaryNumber.add(Integer.parseInt(String.valueOf(numb)));
            }
            allBinaryNumbers.add(singleBinaryNumber);
            System.out.println(allBinaryNumbers); 
            singleBinaryNumber.clear();     
            counter  ;
        }
        
        System.out.println(allBinaryNumbers);
        System.out.println(counter);
        return allBinaryNumbers;
        
    }

My test.txt is this

00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010

CodePudding user response:

You are reusing the same singleBinaryNumber which you clear after you finish populating it. Remember, this is a reference (pointer) which means you are adding the same list rather than new lists on each iteration.

You code should be something like this:

public static ArrayList<ArrayList> dataPrep(){
        ArrayList<ArrayList> allBinaryNumbers = new ArrayList<ArrayList>();
        
        int counter = 0;
      
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            char[] charLine = line.toCharArray();
            
            ArrayList<Integer> singleBinaryNumber = new ArrayList<Integer>(); // create a new list for each iteration 
            for (char numb : charLine){
                singleBinaryNumber.add(Integer.parseInt(String.valueOf(numb)));
            }
            allBinaryNumbers.add(singleBinaryNumber);
            System.out.println(allBinaryNumbers); 
            // singleBinaryNumber.clear(); <-- remove this line
            counter  ;
        }
        
        System.out.println(allBinaryNumbers);
        System.out.println(counter);
        return allBinaryNumbers;
        
    }

CodePudding user response:

I think a better way to go would be to have the readFile() method do exactly that, read the file instead of just opening it and to have this method return an ArrayList. It should also accept a String argument that would be the file path (with file name) rather than hard coding the file path directly in the method itself, for example:

// Class instance member variable with Getter & Setter methods.
private String sourceFile; 

// In your main() method:  
// List of Lists. Each internal list is from a different file.
List<List<String>> filesBinaries = new ArrayList<>(); 

// List for current file to be read.
List<String> binaries = readFile(sourceFile);

// Add the current file List object to the 
// List of Lists (filesBinaries).
if (!binaries.isEmpty()) { 
    filesBinaries.add(binaries);
}

With this, your readFile() method would then possibly look something like this:

public static List<String> readFile(String filePath) throws FileNotFoundException {
    File file = new File(filePath);
    if (!file.exists()) {
        throw new FileNotFoundException("readFile() Method Error! The "
                  "supplied file in the path shown below does not exist!"   System.lineSeparator()
                  file.getAbsolutePath()   System.lineSeparator());
    }

    List<String> binaryLines = new ArrayList<>();
    // 'Try With Resources' is used here to auto-close the reader.
    try (Scanner reader = new Scanner(file)) {
        String line = "";
        while (reader.hasNextLine()) {
            line = reader.nextLine().trim();
            // Data Line Validation:
            /* Skip past blank lines (if any) and any lines
            that do not contain a valid binary string. Valid
            lines would be: 100100  or  00100 11100 01110      */
            if (line.isEmpty() || !line.matches("[01 ] ")) {
                continue;
            }
            binaryLines.add(line);
        }
    }
    return binaryLines;
}

And to fire this method, your main() method might look something like this:

public static void main(String[] args) {
    List<List<String>> filesData = new ArrayList<>();
    String sourceFile = "BinaryData.txt";  // The CURRENT file to read

    try {
        // Read the desired file...
        List<String> binaryData = readFile(sourceFile);
        // If the binaryData list is not empty then add it to the fileData List.
        if (!binaryData.isEmpty()) {
            filesData.add(binaryData);
        }
    }
    catch (FileNotFoundException ex) {
        System.err.println("The file: \""   sourceFile   "\" could not be "
                  "found!"   System.lineSeparator()   ex.getMessage());
    }
    
    // Display the contens of the filesData List...
    for (int i = 0; i < filesData.size(); i  ) {
         System.out.println("File #"   (i   1)   " Binary Data:");
         System.out.println("====================");
         for (String binaryString : filesData.get(i)) {
             System.out.println(binaryString);
         }
    }
}
  •  Tags:  
  • Related