28

私はJavaでさまざまな放課後のクラブ(例:フットボール、ホッケー - ユーザーが入力)を表示するプログラムを書いています。クラブは以下に追加されます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));
}

「Club」はコンストラクタを持つクラスです - 名前:

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(クラブ)をファイルに保存したいので、後でファイルをロードできるようにしたいのですが、同じarraylistが再び存在します。

これには2つの方法があり(以下を参照)、それを機能させようとしてきましたが、うまくいかなかったので、助けやアドバイスをいただければ幸いです。

保存方法 (ファイル名はユーザーが選択)

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

Load メソッド (現在のコードは実行されません - ファイルは文字列ですが、Club にする必要がありますか?

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 を使用してアプリケーションを実行しています。現時点では、[保存] ボタンをクリックして、名前と場所を入力して保存できます。ファイルが表示され、メモ帳で開くことができますが、Club@c5d8jdj のように表示されます (リスト内の各クラブ)。

4

6 に答える 6

80

Java に組み込まれているシリアライゼーション メカニズムを使用する必要があります。それを使用するには、次のことを行う必要があります。

  1. Clubクラスを実装として宣言しSerializableます。

    public class Club implements Serializable {
        ...
    }
    

    これにより、クラスをストリームにシリアライズできることが JVM に通知されます。これはマーカー インターフェイスであるため、メソッドを実装する必要はありません。

  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();
    
于 2013-04-19T19:04:42.697 に答える
13

演習として、次のことをお勧めします。

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
...

積み込みはお任せします。ヒント: 一度に 1 行ずつ書いたので、一度に 1 行ずつ読むことができます。

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();
}
于 2013-04-19T18:55:25.757 に答える
11

Java 8 では、Files.write()Pathメソッドを次のList<String>ような2 つの引数で使用できます。

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);
}
于 2016-05-03T16:01:42.453 に答える
3

これはあなたのために働くかもしれません

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();
}
于 2013-04-19T19:04:28.117 に答える
0
ObjectOutputStream.writeObject(clubs)
ObjectInputStream.readObject();

また、ロジックを「追加」することは、リストの代わりにセットを使用することと論理的に同等です。リストは重複できますが、セットはできません。セットでのご利用をご検討ください。結局のところ、同じ学校に 2 つのチェス クラブを持てるでしょうか?

于 2013-04-19T18:55:50.117 に答える