初心者がJavaでTodo管理システムを作ってみるガイド！

# Java CLI Todo管理システム 実装ガイド

## はじめに
このガイドでは、JavaでCLI（コマンドライン）のTodo管理システムを作成する方法を、初心者向けにステップバイステップで解説します。

## 開発環境の準備
1. JDK (Java Development Kit)をインストール
   - Oracle公式サイトからJDK（最新のバージョン）をダウンロードしてインストール
   - 環境変数のPATHを設定

2. 開発用エディタのインストール
   - VSCode、IntelliJ IDEA、Eclipseのいずれかをインストール
   - この手順ではVSCodeを使用する前提で説明します

詳細は下記記事もチェック！

https://qiita.com/Hemmy7/items/4d49bdb172aa23bc839e


## プロジェクトの作成
1. 新しいフォルダを作成
   - デスクトップに「TodoApp」フォルダを作成
   - その中に「src」フォルダを作成

2. 必要なファイルの作成
   - src フォルダ内に以下のファイルを作成：
     - Todo.java（Todoクラス用）
     - TodoApp.java（メインクラス用）

## ステップ1: Todoクラスの作成
Todo.javaに以下のコードを記述します：

```java
import java.time.LocalDateTime;

public class Todo {
    // フィールド（クラスの属性）
    private int id;             // タスクID
    private String title;       // タスクのタイトル
    private LocalDateTime createdAt;  // 作成日時
    private boolean completed;  // 完了状態

    // コンストラクタ（newでインスタンス化する時に呼ばれる）
    public Todo(int id, String title) {
        this.id = id;
        this.title = title;
        this.createdAt = LocalDateTime.now();
        this.completed = false;
    }

    // getter/setterメソッド
    public int getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public boolean isCompleted() {
        return completed;
    }

    public void setCompleted(boolean completed) {
        this.completed = completed;
    }

    // タスクの情報を文字列で返すメソッド
    @Override
    public String toString() {
        String status = completed ? "[完了]" : "[未完了]";
        return String.format("%d: %s %s", id, title, status);
    }
}
```

## ステップ2: メインアプリケーションの作成
TodoApp.javaに以下のコードを記述します：

```java
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class TodoApp {
    // タスクを保存するリスト
    private static List<Todo> todos = new ArrayList<>();
    // ユーザー入力を受け付けるためのScanner
    private static Scanner scanner = new Scanner(System.in);
    // 次のタスクID用のカウンター
    private static int nextId = 1;

    public static void main(String[] args) {
        // メインループ
        while (true) {
            showMenu();
            int choice = getIntInput();
            
            switch (choice) {
                case 1:
                    addTodo();
                    break;
                case 2:
                    listTodos();
                    break;
                case 3:
                    completeTodo();
                    break;
                case 4:
                    deleteTodo();
                    break;
                case 5:
                    System.out.println("アプリケーションを終了します。");
                    System.exit(0);
                default:
                    System.out.println("無効な選択です。");
            }
        }
    }

    // メニューを表示するメソッド
    private static void showMenu() {
        System.out.println("\n=== Todoアプリケーション ===");
        System.out.println("1: 新規タスクの追加");
        System.out.println("2: タスク一覧の表示");
        System.out.println("3: タスクの完了");
        System.out.println("4: タスクの削除");
        System.out.println("5: アプリケーションの終了");
        System.out.print("選択してください (1-5): ");
    }

    // 新規タスクを追加するメソッド
    private static void addTodo() {
        System.out.print("タスクのタイトルを入力してください: ");
        String title = scanner.nextLine();
        
        Todo todo = new Todo(nextId++, title);
        todos.add(todo);
        System.out.println("タスクが追加されました: " + todo);
    }

    // タスク一覧を表示するメソッド
    private static void listTodos() {
        if (todos.isEmpty()) {
            System.out.println("タスクはありません。");
            return;
        }
        
        System.out.println("\n=== タスク一覧 ===");
        for (Todo todo : todos) {
            System.out.println(todo);
        }
    }

    // タスクを完了させるメソッド
    private static void completeTodo() {
        listTodos();
        if (todos.isEmpty()) return;
        
        System.out.print("完了するタスクのIDを入力してください: ");
        int id = getIntInput();
        
        for (Todo todo : todos) {
            if (todo.getId() == id) {
                todo.setCompleted(true);
                System.out.println("タスクを完了としてマークしました: " + todo);
                return;
            }
        }
        System.out.println("指定されたIDのタスクは見つかりませんでした。");
    }

    // タスクを削除するメソッド
    private static void deleteTodo() {
        listTodos();
        if (todos.isEmpty()) return;
        
        System.out.print("削除するタスクのIDを入力してください: ");
        int id = getIntInput();
        
        for (int i = 0; i < todos.size(); i++) {
            if (todos.get(i).getId() == id) {
                Todo removed = todos.remove(i);
                System.out.println("タスクを削除しました: " + removed);
                return;
            }
        }
        System.out.println("指定されたIDのタスクは見つかりませんでした。");
    }

    // 整数入力を処理するヘルパーメソッド
    private static int getIntInput() {
        try {
            return Integer.parseInt(scanner.nextLine());
        } catch (NumberFormatException e) {
            return -1; // 無効な入力の場合
        }
    }
}
```

## コンパイルと実行方法

1. コードの保存
   - 上記のコードをそれぞれのファイルに保存します
   - 文字コードはUTF-8で保存してください

2. コンパイル
   - コマンドプロンプト（Windowsの場合）またはターミナル（MacやLinuxの場合）を開きます
   - srcフォルダに移動します
   - 以下のコマンドでコンパイルします：
     ```bash
     javac Todo.java TodoApp.java
     ```

3. 実行
   - 以下のコマンドで実行します：
     ```bash
     java TodoApp
     ```

## アプリケーションの使い方

1. タスクの追加
   - メインメニューで「1」を選択
   - タスクのタイトルを入力

2. タスク一覧の表示
   - メインメニューで「2」を選択
   - 全てのタスクが表示されます

3. タスクの完了
   - メインメニューで「3」を選択
   - 完了させたいタスクのIDを入力

4. タスクの削除
   - メインメニューで「4」を選択
   - 削除したいタスクのIDを入力

5. アプリケーションの終了
   - メインメニューで「5」を選択

## 発展的な機能追加のアイデア

基本機能が実装できたら、以下のような機能を追加してみましょう：

1. タスクの期限設定
   - Todoクラスに期限用のフィールドを追加
   - 期限切れタスクの警告表示

2. タスクの優先度設定
   - 優先度を表す列挙型（enum）の作成
   - 優先度による並び替え機能

3. データの永続化
   - ファイルへの保存機能
   - プログラム起動時のデータ読み込み

## トラブルシューティング

よくある問題と解決方法：

1. コンパイルエラー
   - 文法エラーがないか確認
   - クラス名とファイル名が一致しているか確認
   - 必要なimport文が全て含まれているか確認

2. 実行時エラー
   - 入力値の型が正しいか確認
   - nullポインタの可能性をチェック
   - 配列やリストの境界チェック

## まとめ

このTodo管理システムでは以下のJavaの重要な概念を学ぶことができます：

- クラスとオブジェクト指向プログラミング
- 配列とリスト（ArrayList）の使用方法
- ユーザー入力の処理
- 制御構文（if文、switch文、ループ）
- 基本的なエラー処理

このプロジェクトを通じて、実践的なプログラミングスキルを身につけることができます。