ToDoアプリを作成してみよう(Java)

Java

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);
  }
}
Java
スポンサーリンク
シェアする
mjpurinをフォローする

コメント

タイトルとURLをコピーしました