Java | 1 日 90 分 × 7 日アプリ学習 初級編:Map を使うアプリ

Web APP Java
スポンサーリンク

5日目のゴール

5日目のテーマは
「Map を“設定・状態・スコア”を持つための土台として使えるようになること」 です。

ここまでであなたは、

キーで値を引ける
値にオブジェクトを入れられる
Map と List を組み合わせてグループ分けできる

というところまで来ています。

5日目では、もう一歩踏み込んで、

「設定(config)を Map で持つ」
「スコアボードを Map で持つ」
「存在しないキーに対して“デフォルト値”を返す」

という、“アプリの裏側でよく使う Map の顔”を固めていきます。


Map を「設定(config)」として使う

設定ってそもそも何?

アプリには、こんな「設定」がよくあります。

テーマカラー(light / dark)
言語(ja / en)
1ページあたりの表示件数(10 / 20 / 50)

これらは、

「設定名 → 設定値」

という形で表せます。

つまり、Map です。

キー:設定名(String)
値:設定値(String や Integer)

という形になります。

シンプルな設定クラスを作る

まずは「文字列だけで持つ設定」を作ってみます。

import java.util.HashMap;
import java.util.Map;

public class AppConfig {
    Map<String, String> values;

    AppConfig() {
        values = new HashMap<>();
    }

    void set(String key, String value) {
        if (key == null || key.isEmpty()) {
            System.out.println("キーは必須です。");
            return;
        }
        values.put(key, value);
    }

    String get(String key) {
        return values.get(key);
    }
}
Java

ここでやっていることはシンプルです。

Map<String, String> で「設定名 → 設定値」を持つ
setput(key, value) する
getget(key) する

でも、これだけだと少し足りません。


「設定がないとき」の扱いを決める

そのまま get すると null が返る

例えば、こう使ったとします。

AppConfig config = new AppConfig();
config.set("theme", "dark");

System.out.println(config.get("theme"));      // "dark"
System.out.println(config.get("language"));   // null
Java

language は設定していないので、null が返ります。

設定としては、

「設定されていないときは、デフォルト値を使いたい」

ということが多いです。

例えば、

theme のデフォルトは “light”
language のデフォルトは “ja”

など。

getOrDefault という考え方

「なければデフォルト」を毎回 if で書くのは面倒なので、
メソッドにしてしまいます。

String getOrDefault(String key, String defaultValue) {
    String value = values.get(key);
    if (value == null) {
        return defaultValue;
    }
    return value;
}
Java

これで、こう書けます。

String theme = config.getOrDefault("theme", "light");
String language = config.getOrDefault("language", "ja");
Java

ここでの重要ポイントは、

「Map は“設定されていない”という状態も持ちうる」
だからこそ、“なければこれ”というデフォルトを決めておくと扱いやすい

ということです。


数値設定を安全に扱う

文字列から数値に変換する

設定値を全部 String で持つと、
「数値として使いたいとき」に変換が必要になります。

例えば「1ページあたりの表示件数」を pageSize というキーで持つとします。

config.set("pageSize", "20");
Java

これを数値として使いたいときは、こうします。

String raw = config.get("pageSize");
int pageSize;

if (raw == null) {
    pageSize = 10; // デフォルト
} else {
    try {
        pageSize = Integer.parseInt(raw);
    } catch (NumberFormatException e) {
        pageSize = 10; // 変な値が入っていたらデフォルト
    }
}
Java

少し長いですが、やっていることはこうです。

設定がなければデフォルト
あっても数値に変換できなければデフォルト

つまり、

「Map は“何でも入る箱”だからこそ、取り出す側で責任を持って解釈する」

という姿勢が大事になります。


スコアボードを Map で作る

「名前 → スコア」の世界

次は、ゲームのスコアボードを考えてみます。

“alice” → 1200
“bob” → 800
“charlie” → 1500

これはそのまま、

Map<String, Integer>

です。

キー:プレイヤー名
値:スコア

という形になります。

ScoreBoard クラスを作る

import java.util.HashMap;
import java.util.Map;

public class ScoreBoard {
    Map<String, Integer> scores;

    ScoreBoard() {
        scores = new HashMap<>();
    }

    void setScore(String name, int score) {
        if (name == null || name.isEmpty()) {
            System.out.println("名前は必須です。");
            return;
        }
        if (score < 0) {
            System.out.println("スコアは 0 以上にしてください。");
            return;
        }
        scores.put(name, score);
    }

    Integer getScore(String name) {
        return scores.get(name);
    }
}
Java

ここまでは、2日目のカウンターと似ていますね。


「今のスコアより高いときだけ更新する」

ハイスコアの考え方

ゲームでは、

「今回のスコアが、今までのハイスコアより高いときだけ更新する」

というルールがよくあります。

これを Map で書いてみます。

void updateHighScore(String name, int newScore) {
    if (name == null || name.isEmpty()) {
        System.out.println("名前は必須です。");
        return;
    }
    if (newScore < 0) {
        System.out.println("スコアは 0 以上にしてください。");
        return;
    }

    Integer current = scores.get(name);
    if (current == null || newScore > current) {
        scores.put(name, newScore);
        System.out.println(name + " のハイスコアを " + newScore + " に更新しました。");
    } else {
        System.out.println(name + " のハイスコアは " + current + " のままです。");
    }
}
Java

ここでの重要ポイントは、

キーが存在しない(初登場のプレイヤー)なら、そのまま登録
キーが存在するなら、「今の値」と「新しい値」を比較して、条件付きで上書き

というロジックを、
Map の上に素直に乗せていることです。

「Map は“今の状態”を持つ場所であり、put は“状態の更新”」

という感覚が、ここでさらに強くなります。


スコアボードを一覧表示する

keySet で回す

void showAll() {
    System.out.println("=== スコアボード ===");
    if (scores.isEmpty()) {
        System.out.println("まだスコアが登録されていません。");
        return;
    }
    for (String name : scores.keySet()) {
        int score = scores.get(name);
        System.out.println(name + " : " + score);
    }
}
Java

ここはもう、だいぶ見慣れた形ですね。

Map の中身を「全部なめる」ときは、

keySet() でキー一覧を取り出す
キーから get(key) で値を取り出す

というパターンです。


5日目のミニアプリ:設定+スコアボード

AppConfig と ScoreBoard を一緒に使う

最後に、今日の内容をまとめて動かしてみます。

public class Main {
    public static void main(String[] args) {
        AppConfig config = new AppConfig();
        config.set("theme", "dark");
        config.set("language", "ja");
        config.set("pageSize", "20");

        String theme = config.getOrDefault("theme", "light");
        String language = config.getOrDefault("language", "en");
        String pageSizeRaw = config.getOrDefault("pageSize", "10");

        int pageSize;
        try {
            pageSize = Integer.parseInt(pageSizeRaw);
        } catch (NumberFormatException e) {
            pageSize = 10;
        }

        System.out.println("=== 設定 ===");
        System.out.println("theme    : " + theme);
        System.out.println("language : " + language);
        System.out.println("pageSize : " + pageSize);

        ScoreBoard board = new ScoreBoard();
        board.updateHighScore("alice", 1200);
        board.updateHighScore("bob", 800);
        board.updateHighScore("alice", 900);   // 更新されない
        board.updateHighScore("alice", 1500);  // 更新される

        board.showAll();
    }
}
Java

この Main を眺めてみてください。

設定を Map で持つ
「なければデフォルト」という考え方で取り出す
スコアボードを Map で持つ
「今より良いときだけ更新」というロジックを Map の上に乗せる

ここにも、Map という単語はほとんど出てきません。

見えているのは、

設定
テーマ
言語
ページサイズ
スコアボード
ハイスコア

という「アプリの世界」です。

裏側では、

Map<String, String> が設定を
Map<String, Integer> がスコアを

それぞれ key/value の形で支えています。


5日目で絶対に押さえてほしい本質

今日いちばん大事なのは、
「Map は“設定・状態・スコア”のような“今の値”を持つ場所として、とても相性がいい」
という感覚です。

設定名 → 設定値
プレイヤー名 → ハイスコア
ユーザーID → 現在のステータス

どれも形は同じです。

キーは「何を知りたいか」
値は「そのときの答え」

そして、

put は「答えの更新」
get は「今の答えの参照」
「なければデフォルト」という考え方をセットで持つ

ここまで見えてきたら、
Map はもう「ただの key/value の入れ物」ではなく、
「アプリの“今”を表現するための中枢」 に見えてくるはずです。

次のステップでは、
これを List や他のクラスと組み合わせて、
さらに大きな「アプリの世界」を組み立てていけます。

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