Read File into ArrayList from .txt file on begging of program

Viewed 81

So i got a Java Class of Konto, which got:

private String navn;
private int medlemdsnummer;
private String årstal;
private String måned;
private String dag;
LocalDate localDate;

They are used like this:

ArrayList<Konto> kontoArrayList = new ArrayList<>();

And I save my ArrayList to a .txt document before the program shutdowns:

private static void saveToFile(ArrayList<Konto> kontoArrayList) throws IOException {

    String content = new String(Files.readAllBytes(Paths.get("medlemmer.txt")));
    PrintStream printStream = new PrintStream("medlemmer.txt");

    for (int i = 0; i < kontoArrayList.size(); i++) {

        printStream.println(content + kontoArrayList.get(i).getMedlemdsnummer() + ": " + kontoArrayList.get(i).getNavn() + " " +
                kontoArrayList.get(i).getLocalDate());

    }


}

They end up looking like this in the .txt file:

1: Kasper 1996-11-20
2: Jonas 1996-04-27
3: Jesper 1996-05-14

Okay, so far so good. Now for the question: When the program is turned on, I want to make it able to load the .txt file from the beginning and "transfer" it to an ArrayList of Konto. So that i later can use my method (addNewMember). I saw a lot of example on the internet, but they all use:

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

I want to use:

ArrayList<Konto> konto = new ArrayList<Konto>();

Is this possible, if so how do to? If not what could i do instead?

Thanks in advance, Victor.

3 Answers

I think one way you can try is read line by line, and define a Konto constructor that accept a string.

Edit: You can follow the below answer from Lucem. But I think I will do it a little different

List<String> strings = Files.readAllLines(Paths.get("fileName.txt"));
List<Konto> kontos = new ArrayList<>();
for (String s: strings) {
    kontos.add (new Konto(s))
}

or using Streams:

List<Konto> kontos = Files.lines(Paths.get("fileName.txt"))
    .map(line -> new Konto(line));
    .collect(Collectors.toList());

And then in Konto class add a constructor that accept a string and manipulate it. Because you didn't add the class Konto here, I didn't know the exact name of your properties, so I let it be "yourPropertyNumber", "yourPropertyString" and "yourPropertyDate"

class Konto {
    public Konto (String input) {
        // Split based on white space 
        String[] dataParts = input.split(" ");

        // Get rid of the semicolon
        String number = dataParts[0].substring(0, dataParts[0].length - 1);
        yourPropertyNumber = parseInt(number);
        yourPropertyString = dataParts[1];
        yourPropertyDate = new Date(dataParts[2]);
    }
    // Your other code here
}

The reason I want to pass a String to a constructor rather than parse the string where I read the file is that I think it is easier to debug or make change in the way it reads the string.

Hope this help.

Something like the following, you've got to check it

class TestParse {
    public TestParse(String line) {
        StringTokenizer tokenizer = new StringTokenizer(line, ",");

        if(tokenizer.countTokens() != 3) {
            throw new RuntimeException("error");        
        }

        s1 = tokenizer.nextToken();
        s2 = tokenizer.nextToken();
        s3 = tokenizer.nextToken();
    }

    private String s1;
    private String s2;
    private String s3;
}

public class TestRead {
    public static void main(String[] args) throws Exception {
        List<TestParse> testParses = new ArrayList<TestParse>();

        BufferedReader in = new BufferedReader(new FileReader("file.txt"));

        String line;

        while((line = in.readLine()) != null) {
            testParses.add(new TestParse(line));
        }

        in.close(); 
    }
}

You can read all lines from the file as string and split this strings by spaces. And then create new objects with parsing of options. Something like this:

List<String> strings = Files.readAllLines(Paths.get("test.txt"));
List<Konto> kontos = new ArrayList<>();
for (String string : strings) {
    String[] data = string.split(" ");
    kontos.add(new Konto(data[1], new Date(data[2])));
}

Or using Streams:

List<Konto> kontos = Files.lines(Paths.get("test.txt"))  // String
    .map(line -> line.split(" "))                        // String[]
    .map(data -> new Konto(data[1], new Date(data[2]))   // Konto
    .collect(Collectors.toList());
Related