Javaでオブジェクト指向や、ArrayListなどを学び始めた段階での演習問題。
ファイルの読み書きを使ってデータの永続化も図る。
これは前回のねこあつめの演習問題として行ったので、まずはそちらをやることをおすすめする。
実行例
まずはいつものように実行例から
****TodoApp****
Todoは1件もありません。
——操作を入力してください。——
1/登録 2/重要度変更 3/削除 4/終了>1
新規Todoを作成します。
Todo内容を入力してください>ミルクを買う
重要度を1~10(最大)で入力してください>3
1件追加しました。
0・・・ミルクを買う/重要度:3
——操作を入力してください。——
1/登録 2/重要度変更 3/削除 4/終了>1
新規Todoを作成します。
Todo内容を入力してください>銀行へ行く (預入)
重要度を1~10(最大)で入力してください>10
1件追加しました。
0・・・銀行へ行く (預入)/重要度:10
1・・・ミルクを買う/重要度:3
——操作を入力してください。——
1/登録 2/重要度変更 3/削除 4/終了>1
新規Todoを作成します。
Todo内容を入力してください>キャットフードを買う
重要度を1~10(最大)で入力してください>5
1件追加しました。
0・・・銀行へ行く (預入)/重要度:10
1・・・キャットフードを買う/重要度:5
2・・・ミルクを買う/重要度:3
——操作を入力してください。——
1/登録 2/重要度変更 3/削除 4/終了>2
重要度を変更します。番号を入力してください。0~2>2
重要度を再設定してください。>7
重要度を変更しました。
0・・・銀行へ行く (預入)/重要度:10
1・・・ミルクを買う/重要度:7
2・・・キャットフードを買う/重要度:5
——操作を入力してください。——
1/登録 2/重要度変更 3/削除 4/終了>3
Todoを削除します。番号を入力してください。0~2>2
1件削除しました。
0・・・銀行へ行く (預入)/重要度:10
1・・・ミルクを買う/重要度:7
——操作を入力してください。——
1/登録 2/重要度変更 3/削除 4/終了>4
アプリケーションを終了します。
仕様
○正常系のみを考慮すればよい(重要度の入力は必ず1-10が入力されるなど、想定外の入力に対する処理は不必要)
○例外処理はthrows宣言のみでよい
作成
まずはファイルの読み書きがない状態でアプリを作成する。
以下のようにToDoApp.javaを作成する。
import java.util.*;
import java.io.*;
public class ToDoApp{
public static void main(String[] args) throws Exception{
}
}
class ToDo{
}
一般クラス ToDoの作成
class ToDo{
//フィールド
String title;
int importance;
//コンストラクタ
ToDo(String title,int importance){
this.title=title;
this.importance=importance;
}
//インスタンスメソッド
String showStatus(){
return String.format("%s/重要度:%d",this.title,this.importance);
}
void changeImportance(int importance){
this.importance=importance;
System.out.println("重要度を変更しました。");
}
}
アプリケーションクラス ToDoAppの作成
public class ToDoApp{
public static void main(String[] args) throws Exception{
Scanner sc = new Scanner(System.in);
ArrayList<ToDo> list = new ArrayList<>();
while(true){
System.out.println("——操作を入力してください。——");
System.out.print("1/登録 2/重要度変更 3/削除 4/終了>");
int select = sc.nextInt();
switch(select){
case 1:
addItem(list,sc);
break;
case 2:
updateItem(list,sc);
break;
case 3:
deleteItem(list,sc);
break;
default:
System.out.println("アプリケーションを終了します。");
return;
}
displayList(list);
}
}
static void sortList(ArrayList<ToDo> list){
for(int i=0;i<list.size()-1;i++){
for(int j=i+1;j<list.size();j++){
if(list.get(i).importance < list.get(j).importance){
ToDo temp = list.get(i);
list.set(i,list.get(j));
list.set(j,temp);
}
}
}
}
static void displayList(ArrayList<ToDo> list){
sortList(list);
for(int i=0;i<list.size();i++){
System.out.printf("%d・・・%s%n",i,list.get(i).showStatus());
}
}
static void addItem(ArrayList<ToDo> list,Scanner sc){
System.out.println("新規ToDoを作成します。");
System.out.print("Todo内容を入力してください>>");
String title=sc.next();
System.out.print("重要度を1~10(最大)で入力してください>>");
int importance = sc.nextInt();
ToDo t = new ToDo(title,importance);
list.add(t);
}
static void updateItem(ArrayList<ToDo> list,Scanner sc){
if(list.size() == 0){
System.out.println("まだToDoがありません");
return;
}
System.out.printf("重要度を変更します。番号を入力してください。0~%d>>",list.size()-1);
int no = sc.nextInt();
ToDo t = list.get(no);
System.out.print("重要度を再設定してください>>");
int importance=sc.nextInt();
t.changeImportance(importance);
}
static void deleteItem(ArrayList<ToDo> list,Scanner sc){
System.out.printf("Todoを削除します。番号を入力してください。0~%d>",list.size()-1);
int no = sc.nextInt();
list.remove(no);
System.out.println("1件削除しました。");
}
}
データのセーブ&ロード
まずはToDoクラスにインスタンスの情報をcsvにするメソッドを追記する
class ToDo{
String title;
int importance;
ToDo(String title,int importance){
this.title=title;
this.importance=importance;
}
String showStatus(){
return String.format("%s/重要度:%d",this.title,this.importance);
}
void changeImportance(int importance){
this.importance=importance;
System.out.println("重要度を変更しました。");
}
String toCSV(){
return String.format("%s,%d",this.title,this.importance);
}
}
ToDoAppクラスに以下の2つのメソッドを追記
static ArrayList<ToDo> loadFile(File file) throws Exception{
//リターンするlistを作成
ArrayList<ToDo> list =new ArrayList<>();
//読み込みはfis
FileInputStream fis=new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
BufferedReader br = new BufferedReader(isr);
//読み込み時のイディオム
String line;
while((line = br.readLine())!=null){
//csvデータなのでカンマでsplit
String[] values=line.split(",");
//タイトルの取り出し
String title=values[0];
//重要度の取り出し
int importance=Integer.parseInt(values[1]);
//2つの情報をもとにToDoインスタンスを作成
ToDo t = new ToDo(title,importance);
//リストに加える
list.add(t);
}
//br終了処理
br.close();
//作成されたlistを返却する
return list;
}
static void saveFile(File file,ArrayList<ToDo> list) throws Exception{
//書き込みはfos
FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
//引数で受け取ったlistを拡張for文で回す
for(ToDo c :list){
//インスタンスの情報をcsvで書き込む
bw.write(c.toCSV());
//改行
bw.newLine();
}
//ファイルを閉じる
bw.close();
}
mainメソッドを以下のように変更する
Scanner sc = new Scanner(System.in);
File file=new File("todo.csv");
ArrayList<ToDo> list;
if(file.exists()){
list = loadFile(file);
}else{
list = new ArrayList<>();
}
if(list.size() == 0){
System.out.println("ToDoは1件もありません");
}else{
displayList(list);
}
while(true){
完成
実行してみよう。
データの永続化ができたので、アプリを一旦終了してもデータが保存されていることがわかる。
全コード
import java.util.*;
import java.io.*;
public class ToDoApp{
public static void main(String[] args) throws Exception{
Scanner sc = new Scanner(System.in);
File file=new File("todo.csv");
ArrayList<ToDo> list;
if(file.exists()){
list = loadFile(file);
}else{
list = new ArrayList<>();
}
if(list.size() == 0){
System.out.println("ToDoは1件もありません");
}else{
displayList(list);
}
while(true){
System.out.println("——操作を入力してください。——");
System.out.print("1/登録 2/重要度変更 3/削除 4/終了>");
int select = sc.nextInt();
switch(select){
case 1:
addItem(list,sc);
break;
case 2:
updateItem(list,sc);
break;
case 3:
deleteItem(list,sc);
break;
default:
System.out.println("アプリケーションを終了します。");
saveFile(file,list);
return;
}
displayList(list);
}
}
static void sortList(ArrayList<ToDo> list){
for(int i=0;i<list.size()-1;i++){
for(int j=i+1;j<list.size();j++){
if(list.get(i).importance < list.get(j).importance){
ToDo temp = list.get(i);
list.set(i,list.get(j));
list.set(j,temp);
}
}
}
}
static void displayList(ArrayList<ToDo> list){
sortList(list);
for(int i=0;i<list.size();i++){
System.out.printf("%d・・・%s%n",i,list.get(i).showStatus());
}
}
static void addItem(ArrayList<ToDo> list,Scanner sc){
System.out.println("新規ToDoを作成します。");
System.out.print("Todo内容を入力してください>>");
String title=sc.next();
System.out.print("重要度を1~10(最大)で入力してください>>");
int importance = sc.nextInt();
ToDo t = new ToDo(title,importance);
list.add(t);
}
static void updateItem(ArrayList<ToDo> list,Scanner sc){
if(list.size() == 0){
System.out.println("まだToDoがありません");
return;
}
System.out.printf("重要度を変更します。番号を入力してください。0~%d>>",list.size()-1);
int no = sc.nextInt();
ToDo t = list.get(no);
System.out.print("重要度を再設定してください>>");
int importance=sc.nextInt();
t.changeImportance(importance);
}
static void deleteItem(ArrayList<ToDo> list,Scanner sc){
System.out.printf("Todoを削除します。番号を入力してください。0~%d>",list.size()-1);
int no = sc.nextInt();
list.remove(no);
System.out.println("1件削除しました。");
}
static ArrayList<ToDo> loadFile(File file) throws Exception{
//リターンするlistを作成
ArrayList<ToDo> list =new ArrayList<>();
//読み込みはfis
FileInputStream fis=new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
BufferedReader br = new BufferedReader(isr);
//読み込み時のイディオム
String line;
while((line = br.readLine())!=null){
//csvデータなのでカンマでsplit
String[] values=line.split(",");
//タイトルの取り出し
String title=values[0];
//重要度の取り出し
int importance=Integer.parseInt(values[1]);
//2つの情報をもとにToDoインスタンスを作成
ToDo t = new ToDo(title,importance);
//リストに加える
list.add(t);
}
//br終了処理
br.close();
//作成されたlistを返却する
return list;
}
static void saveFile(File file,ArrayList<ToDo> list) throws Exception{
//書き込みはfos
FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
//引数で受け取ったlistを拡張for文で回す
for(ToDo c :list){
//インスタンスの情報をcsvで書き込む
bw.write(c.toCSV());
//改行
bw.newLine();
}
//ファイルを閉じる
bw.close();
}
}
class ToDo{
String title;
int importance;
ToDo(String title,int importance){
this.title=title;
this.importance=importance;
}
String showStatus(){
return String.format("%s/重要度:%d",this.title,this.importance);
}
void changeImportance(int importance){
this.importance=importance;
System.out.println("重要度を変更しました。");
}
String toCSV(){
return String.format("%s,%d",this.title,this.importance);
}
}
コメント