从程序开始时将文件读入ArrayList的方法来自.txt文件

3

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;

它们的使用方式如下:
ArrayList<Konto> kontoArrayList = new ArrayList<>();

程序关闭前,我会将ArrayList保存到一个txt文档中:

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());

    }


}

在 .txt 文件中它们最终会呈现如下形式:
1: Kasper 1996-11-20
2: Jonas 1996-04-27
3: Jesper 1996-05-14

好的,目前为止都很顺利。现在是问题:当程序启动时,我希望它能够从一开始就加载.txt文件并将其“转移”到Konto的ArrayList中,以便之后可以使用我的方法(addNewMember)。我在互联网上看到了很多例子,但它们都使用:
ArrayList<String> somename = new ArrayList<String>();

我想使用:
ArrayList<Konto> konto = new ArrayList<Konto>();

这是否可能?如果是,如何操作?如果不行,我该怎么办?

谢谢您,Victor。

3个回答

0

我认为你可以尝试逐行阅读,并定义一个接受字符串的Konto构造函数。

编辑:您可以按照Lucem的下面答案进行操作。但我认为我会稍微有所不同。

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

或者使用Stream

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

然后在Konto类中添加一个接受字符串并对其进行操作的构造函数。由于您没有在此处添加Konto类,我不知道您属性的确切名称,因此我将其命名为“yourPropertyNumber”,“yourPropertyString”和“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
}

我想将一个字符串传递给构造函数而不是在读取文件时解析字符串的原因是,我认为这样更容易调试或更改读取字符串的方式。
希望这可以帮到你。

你能给我展示一下吗?我目前还是个学生,经验不是很丰富 :) - user8767767
我已经编辑了我的答案,使其更加清晰。虽然我不是专业人士,但我希望它能对你有所帮助。祝你好运。 - LdBach

0

像下面这样,你必须检查它

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(); 
    }
}

现在,您应该使用Java的新I/O API称为NIO来读取文件,它围绕着类FilesPathsPath展开。 - Zabuzard
你可以抛出更合适的异常,例如 new IllegalArgumenException("Incorrect amount of tokens"),而不是 new RuntimeException("error") - Zabuzard
谢谢,我会看一下NIO。至于异常处理,是的,这只是一个在任何错误发生时都会死亡且没有错误处理的示例。 - Abdul Ahad

0
你可以将文件中的所有行作为字符串读取,并通过空格拆分这些字符串。然后使用选项解析创建新对象。就像这样:
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])));
}

或者使用 Stream

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());

1
请注意,Date类是过时的。请改用java.time包中的类。 - Zabuzard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接