Java – 如何写我的ArrayList到一个文件,并读取(加载)该文件到原始的ArrayList?

我正在编写一个Java程序,其中显示了一系列的课后俱乐部(EG Football,曲棍球 – 由用户input)。 俱乐部被添加到以下ArrayList

 private ArrayList<Club> clubs = new ArrayList<Club>(); 

通过以下方法:

 public void addClub(String clubName) { Club club = findClub(clubName); if (club == null) clubs.add(new Club(clubName)); } 

'俱乐部'是一个带有构造函数的类 – 名字:

 public class Club { private String name; public Club(String name) { this.name = name; } //There are more methods in my program but don't affect my query.. } 

我的程序正在工作 – 它可以让我添加一个新的俱乐部对象到我的数组列表,我可以查看数组列表,我可以删除任何我想要的东西等。

但是,我现在想要将该数组列表(俱乐部)保存到一个文件,然后我希望能够稍后加载文件,同样arraylist再次存在。

我有两种方法(见下文),一直试图让它工作,但没有任何的,任何帮助或build议,将不胜感激。

保存方法(文件名由用户select)

 public void save(String fileName) throws FileNotFoundException { String tmp = clubs.toString(); PrintWriter pw = new PrintWriter(new FileOutputStream(fileName)); pw.write(tmp); pw.close(); } 

加载方法(当前代码不会运行 – 文件是一个string,但需要俱乐部?

 public void load(String fileName) throws FileNotFoundException { FileInputStream fileIn = new FileInputStream(fileName); Scanner scan = new Scanner(fileIn); String loadedClubs = scan.next(); clubs.add(loadedClubs); } 

我也使用GUI来运行应用程序,目前,我可以点击我的保存button,然后允许我键入一个名称和位置并保存它。 该文件出现,可以在记事本中打开,但显示为像Club @ c5d8jdj(对于我的列表中的每个俱乐部)

作为一个练习,我会build议做以下几点:

 public void save(String fileName) throws FileNotFoundException { PrintWriter pw = new PrintWriter(new FileOutputStream(fileName)); for (Club club : clubs) pw.println(club.getName()); pw.close(); } 

这将在您的文件中的新行上写上每个俱乐部的名称。

 Soccer Chess Football Volleyball ... 

我会把加载给你 提示 :你一次写了一行,然后你可以一次读一行。

Java中的每个类都扩展了Object类。 这样你可以覆盖它的方法。 在这种情况下,您应该通过toString()方法感兴趣。 在您的Club课程中,您可以覆盖它,以任何您喜欢的格式打印关于课程的一些消息。

 public String toString() { return "Club:" + name; } 

然后,您可以将上面的代码更改为:

 public void save(String fileName) throws FileNotFoundException { PrintWriter pw = new PrintWriter(new FileOutputStream(fileName)); for (Club club : clubs) pw.println(club); // call toString() on club, like club.toString() pw.close(); } 

您应该使用Java的内置序列化机制。 要使用它,您需要执行以下操作:

  1. Club类声明为实现Serializable

     public class Club implements Serializable { ... } 

    这告诉JVM该类可以被序列化为一个stream。 你不必实现任何方法,因为这是一个标记接口。

  2. 要将列表写入文件,请执行以下操作:

     FileOutputStream fos = new FileOutputStream("t.tmp"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(clubs); oos.close(); 
  3. 要从文件读取列表,请执行以下操作:

     FileInputStream fis = new FileInputStream("t.tmp"); ObjectInputStream ois = new ObjectInputStream(fis); List<Club> clubs = (List<Club>) ois.readObject(); ois.close(); 

这可能适合你

 public void save(String fileName) throws FileNotFoundException { FileOutputStream fout= new FileOutputStream (fileName); ObjectOutputStream oos = new ObjectOutputStream(fout); oos.writeObject(clubs); fout.close(); } 

回头看,你可以有

 public void read(String fileName) throws FileNotFoundException { FileInputStream fin= new FileInputStream (fileName); ObjectInputStream ois = new ObjectInputStream(fin); clubs= (ArrayList<Clubs>)ois.readObject(); fin.close(); } 

在Java 8中,可以使用带有两个参数的Files.write()方法: PathList<String> ,如下所示:

 List<String> clubNames = clubs.stream() .map(Club::getName) .collect(Collectors.toList()) try { Files.write(Paths.get(fileName), clubNames); } catch (IOException e) { log.error("Unable to write out names", e); } 
 ObjectOutputStream.writeObject(clubs) ObjectInputStream.readObject(); 

此外,您“添加”逻辑在逻辑上等同于使用Set而不是List。 列表可以有重复,集不能。 你应该考虑使用一套。 毕竟,你能在同一所学校真的有两个国际象棋俱乐部吗?