アプリ版:「スタンプのみでお礼する」機能のリリースについて

テキストファイルを1行ずつ読み込んでArrayListに格納し、
格納したものを逆から1行ずつ別のテキストファイルに出力したいのですが、
「逆順に出力」ができなくて困っています。

現在のコードです(長いのでimportは省略します)。
インデント消えていたらすみません。

public class test{
public static void main(String[] args){
try {
Scanner scan = new Scanner(System.in);
System.out.println("読み込むファイル名を指定");
String x = scan.next();
File file = new File(x);
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);

System.out.println("出力するファイル名を指定");
String y = scan.next();
File file2 = new File(y);
FileOutputStream fos = new FileOutputStream(file2);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);

if (file.exists()){
String line = br.readLine();
String newline = "\n";
//リストを作成
List<String> list = new ArrayList<>();
//読み込んだデータを格納
while ((line = br.readLine()) != null) {
//ArrayListに追加する
list.add(line);
//指定したファイルに出力
bw.write(line);
bw.write(newline);
}
//最終行から逆順に1行目まで出力←これができていません
Collections.reverse(list);
bw.write(line);
bw.write(newline);

br.close();
bw.close();
}
else {
System.out.println("ファイルは存在しません");
}
}
catch (IOException e){
System.out.println(e);
}
}
}

ArrayListの要素を逆順にファイルに出力するにはどう修正したらよいでしょうか…?
java詳しい方ご教示いただけますと幸いです。

A 回答 (3件)

何か所かバグがありますが、質問の「逆順に出す」という点だけ見れば、



-----------------------
//最終行から逆順に1行目まで出力←これができていません
Collections.reverse(list);
bw.write(line);
-----------------------

reverseを呼ぶところまではいいのですが、そのままBufferedWriter に渡すことができません。
wirte メソッドで受け取れるのは、以下のどちらかです。

 write(String)
 write(char[])

コードを生かすのであれば、Listの中身を、Stringで取り出すため、以下のように書き換えます。

-----------------------
//最終行から逆順に1行目まで出力←これができていません
Collections.reverse(list);
for (String s : list) {
bw.write(s);
}
-----------------------
    • good
    • 2

実装言語によらず。

。。

配列に順番にデータを入れて行く際。何番目に入れるか(=何番目を操作対象とするか)を指定する変数(カウンター変数)を設けます。
先頭から順に入れて行く場合、この変数の値は0、1、2、・・・とインクリメントされて行くのが一般的です。

で。
上記の操作で出来上がった配列の最後から順に取り出すのであれば、上記の処理が終わった時点ではその処理に用いたカウンター変数は最後にデータを入れた場所を指しています。
ですから上記の処理に続いて取り出す操作を行うのであれば、そのカウンター変数をそのまま使用し、順次デクリメントして行けば配列の最後から先頭に向かって順番に処理できることになります。

このようなことは実装言語によらない設計の部分です。
参考まで。
    • good
    • 1

処理順序は以下になると思います。


1. list を用意
2. 全行を順に入力し list に追加
3. list を並び変える
4. list を順に全行分を出力する

ご提示のプログラムの修正ポイントは
1. より前で一行分の入力は不要
2. で出力も行っているのは不要
4. で全行分を出力していない

ArrayList を繰り返しすならば
for (var item : list) { ... } 構文がお勧めです。
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!