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的内置序列化机制。 要使用它,您需要执行以下操作:
-
将
Club
类声明为实现Serializable
:public class Club implements Serializable { ... }
这告诉JVM该类可以被序列化为一个stream。 你不必实现任何方法,因为这是一个标记接口。
-
要将列表写入文件,请执行以下操作:
FileOutputStream fos = new FileOutputStream("t.tmp"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(clubs); oos.close();
-
要从文件读取列表,请执行以下操作:
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()方法: Path
和List<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。 列表可以有重复,集不能。 你应该考虑使用一套。 毕竟,你能在同一所学校真的有两个国际象棋俱乐部吗?