Java | ミニアプリ:メニュー選択プログラム(switch文)

Java Java
スポンサーリンク

Stream API でのメニューリファクタリング

ここからは少し応用編です。1ページ目のユーザー入力付きメニューStream API でリファクタリングして、よりモダンなJava設計にしてみましょう。

Stream API は本来「コレクションのデータ処理」を簡潔に書くための機能ですが、メニューの処理も「リスト+マッピング」で整理できます。


1. 考え方

  • メニュー番号と処理を Map<Integer, Runnable> で対応付ける
  • switch 文の代わりに、入力値で Map を検索 → 存在すれば実行
  • 存在しなければ「無効な番号」と表示

2. コード例

import java.util.*;
import java.util.stream.*;

public class MenuAppStream {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // メニュー番号と処理をマッピング
        Map<Integer, Runnable> menuMap = Map.of(
            1, () -> System.out.println("→ 商品一覧を表示します。\n"),
            2, () -> {
                System.out.print("検索したい商品名を入力してください: ");
                String keyword = scanner.nextLine();
                System.out.println("→ 「" + keyword + "」を検索しました。\n");
            },
            3, () -> System.out.println("→ 購入手続きに進みます。\n"),
            0, () -> {
                System.out.println("→ プログラムを終了します。");
            }
        );

        while (true) {
            System.out.println("=== メニュー ===");
            System.out.println("1: 商品一覧を見る");
            System.out.println("2: 商品を検索する");
            System.out.println("3: 購入手続きへ進む");
            System.out.println("0: 終了する");
            System.out.print("番号を選んでください: ");

            int choice = -1;
            try {
                choice = Integer.parseInt(scanner.nextLine());
            } catch (NumberFormatException e) {
                System.out.println("→ 数字を入力してください。\n");
                continue;
            }

            // Stream APIで処理実行
            Optional.ofNullable(menuMap.get(choice))
                    .ifPresentOrElse(
                        Runnable::run,                       // 処理があれば実行
                        () -> System.out.println("→ 無効な番号です。\n") // なければメッセージ
                    );

            if (choice == 0) break; // 0ならループ終了
        }

        scanner.close();
    }
}
Java

3. コード解説(初心者向けにやさしく)

ポイント説明
Map<Integer, Runnable>メニュー番号をキーに、処理(Runnable)を値として登録
Optional.ofNullable(menuMap.get(choice))入力番号に対応する処理を取得。なければ null で Optional が空になる
.ifPresentOrElse(...)処理が存在すれば run() 実行、なければ無効番号のメッセージ
choice == 00 を入力したらループを終了(プログラム終了)
scanner.nextLine()数字入力のあとに改行を吸収するため、nextInt より nextLine の方が安全

4. この設計のメリット

  1. switch 文不要 → メニュー追加・変更が簡単 menuMap.put(4, () -> System.out.println("新メニュー追加!"));
  2. 関数型スタイルで簡潔 → 処理を個別にラムダで定義できる
  3. Optional で安全 → 存在しない入力に対して null チェック不要
  4. 実務応用 → GUIやWebアプリでも「番号やIDに対して処理をマッピングする」考え方はそのまま応用可能

5. さらに応用できるアイデア

  • 入力チェックや例外処理をもっと厳密にして、文字列入力にも対応
  • メニュー構造を 別クラス(Serviceクラス)に切り出す
  • GUIやWebのボタンIDを Map と Runnable で管理するパターンにも応用可能

まとめ

  • 従来の switch は条件が増えると冗長になりがち
  • Stream API + Map を使うと 可読性・拡張性が高いメニュー管理 が可能
  • ラムダ式で処理を登録できるため、プログラムの変更が簡単

もしよければ次のステップとして、Mainクラス+Serviceクラスに分けた実務風メニュー設計も作れます。
これは「この Stream API メニューをさらにきれいに整理する方法」です。

作ってみますか?

Java
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました