Instantiate an ArrayList by reading in lines from a Scanner, where to declare object?

Viewed 1446

I'd like to populate an array list with lines from an input file, the input file looks like this:

7f00000000000000000000000000000000000000000000000000000000000000027f00000000000000000000000000000000000000000000000000000000000000027f00000000000000000000000000000000000000000000000000000000000000020101
7f00000000000000000000000000000000000000000000000000000000000000037f00000000000000000000000000000000000000000000000000000000000000037f00000000000000000000000000000000000000000000000000000000000000030101
7f00000000000000000000000000000000000000000000000000000000000000047f00000000000000000000000000000000000000000000000000000000000000047f00000000000000000000000000000000000000000000000000000000000000040101
7f00000000000000000000000000000000000000000000000000000000000000057f00000000000000000000000000000000000000000000000000000000000000057f00000000000000000000000000000000000000000000000000000000000000050101
7f00000000000000000000000000000000000000000000000000000000000000067f00000000000000000000000000000000000000000000000000000000000000067f00000000000000000000000000000000000000000000000000000000000000060101

The data object in Java that I'd like to create based on this would have each one of those lines as a new string, and they would live together in a list, so to speak*.

So, in my attempt to read in the lines of the file into different components of this array list, I can't figure out where I need to declare the array list in my main program. My plan is to populate it in a separate method:

import java.io.*;
import java.util.Scanner;
import java.util.List;
import java.util.Array;
import java.util.ArrayList;

class evmTest {

public static void main(String[] args) {


    Array<String> inputLinesObject = new ArrayList<String>();

    // populate from file
    inputLinesObject = readFile("/Users/s.matthew.english/codes.txt", inputLinesObject);


    System.out.println(Array.toString(inputLinesObject));

}

    private static void readFile(String fileName, Array<String> inputLines) {
        try {
            File file = new File(fileName);
            Scanner scanner = new Scanner(file);
            while (scanner.hasNextLine()) {
                // System.out.println(scanner.nextLine());
                inputLines.add(scanner.nextLine());
            }
            scanner.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return inputLines;
    }

}

Maybe I can initially instantiate it as null, and then pass that null array list to the method to be populated?

* The terms in that last sentence are not totally precise- please forgive me- I'm re-adjusting to the vocabulary of Java, nevertheless I think it should be clear enough what I'm trying to do. If not please let me know and I'll be happy to clarify.

4 Answers

For your test, you simply have to instantiate the ArrayList just above the try

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

public class EvmTest {

    public static void main(final String[] args) {
        // populate from file
        final List<String> inputLinesObject = EvmTest.readFile("/Users/s.matthew.english/codes.txt");

        for (final String line : inputLinesObject) {
            System.out.println(line);
        }
    }

    private static List<String> readFile(final String fileName) {
        final List<String> inputLinesObject = new ArrayList<>();

        try {
            final File file = new File(fileName);
            final Scanner scanner = new Scanner(file);
            while (scanner.hasNextLine()) {
                // System.out.println(scanner.nextLine());
                inputLinesObject.add(scanner.nextLine());
            }
            scanner.close();
        } catch (final FileNotFoundException e) {
            e.printStackTrace();
        }
        return inputLinesObject;
    }
}

That has 2 advantages: - You don't modify an input parameter of your readFile method - You don't have to handle the case where the List is empty or null

You actually have three options:

  1. Pass in a presumably empty list as a parameter into the method, and then add elements to the list:

    static void readFile(String filename, List<String> inputLines) {
        // For each line
        inputLines.add(line);
    }
    

    You can then call is this way:

    List<String> inputLines = new ArrayList<>();
    readFile("someFilename", inputLines);
    
  2. Let the readFile() method return a list:

    static List<String> inputLines(String filename) {
        List<String> lines = new ArrayList<>();
        // For each line
        lines.add(line);
    
        // And then return the list with lines:
        return lines;
    }
    

    And then call it this way:

    List<String> lines = readFile("someFilename");
    
  3. Don't reinvent the wheel and use functional programming to get the lines of the file:

    List<String> lines = Files.lines(Paths.get("somefile"))
        .collect(Collectors.toList());
    

The second one is way better than the first one, since it leaves the responsibility to create the list to the method itself. However, the latter is the best option.


A few more things:

  • Stick to the Java Naming Conventions: class names should start with uppercase.
  • You are using an Array<String>, but java.util.Arrray doesn't exist. I assume you mean List<String>.

Create a singleton class with a composition of ArrayList.

You can create a sinleton like this

import java.util.ArrayList;
import java.util.List;

public class FileLines {

    private List<String> lines;

    private FileLines() {
        lines = new ArrayList();
    }

    private static class FileListHolder {

        private final static FileLines instance = new FileLines();
    }

    public static FileLines getInstance() {
        return FileListHolder.instance;
    }

    public void addLine(String line) {
        lines.add(line);
    }

    public String getLine(int lineNumber) {
        return lines.get(lineNumber);
    }

}

and in your main program use it

FileLines fileLines = FileLines.getInstance();
fileLines.addLine(scanner.nextLine());

And in other part of your programm you can retrieve a line with

FileLines fileLines = FileLines.getInstance();
fileLines.getLine(12);

Use this code for readFile() method:

private static List<String> readFile(String fileName, List<String> inputLines) {
    try {
        File file = new File(fileName);
        Scanner scanner = new Scanner(file);
        while (scanner.hasNextLine()) {
            // System.out.println(scanner.nextLine());
            inputLines.add(scanner.nextLine());
        }
        scanner.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    return inputLines;
}

and then call this readFile() method as below:

List<String> inputLinesObject = new ArrayList<String>();
inputLinesObject = readFile("/Users/s.matthew.english/codes.txt", inputLinesObject);

for(String str : inputLinesObject){
     System.out.println(str);
}
Related