3日目のゴール
3日目のテーマは
「Map の value に“オブジェクト”を入れて、現実っぽいデータを扱えるようになること」 です。
1〜2日目であなたはすでに、
key は「名前・ID・ラベル」
value は「本当に知りたい中身」put / get / containsKey / remove / keySet などの基本操作
を押さえました。
3日目ではここから一歩進んで、
value にクラス(オブジェクト)を入れる
「ID → User」「商品コード → 商品情報」のような Map を作る
Map を“検索のショートカット”として使う
という、アプリ開発でめちゃくちゃよく出てくるパターンを身につけます。
まずは「ユーザー1人分」をクラスで表現する
User クラスを作る
「ユーザー管理」を題材にします。
まずは、1人分のユーザー情報をクラスにします。
public class User {
String id; // ユーザーID(ユニーク)
String name; // 名前
String email; // メールアドレス
User(String id, String name, String email) {
if (id == null || id.isEmpty()) {
throw new IllegalArgumentException("ID は必須です。");
}
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("名前は必須です。");
}
if (email == null || email.isEmpty()) {
throw new IllegalArgumentException("メールアドレスは必須です。");
}
this.id = id;
this.name = name;
this.email = email;
}
void show() {
System.out.println("ID: " + id + " / 名前: " + name + " / メール: " + email);
}
}
Javaここで大事なのは、
「1人分の情報をひとまとまりにする」
「ID は必須で、ユニーク(重複しない)という前提で扱う」
という2点です。
この「ID が一意」という前提が、
Map と相性バツグンです。
Map<String, User> という形を理解する
「ID → User」の対応表を作る
次に、ユーザーを管理するための Map を作ります。
import java.util.HashMap;
import java.util.Map;
public class UserDirectory {
Map<String, User> users;
UserDirectory() {
users = new HashMap<>();
}
}
JavaMap<String, User> は、
key:ユーザーID(String)
value:User オブジェクト
という意味です。
1〜2日目は Map<String, String> や Map<String, Integer> でしたが、
今日は value に「自分で作ったクラス」を入れています。
ここが、3日目の一番大きなステップです。
ユーザーを登録する(put の応用)
addUser メソッド
void addUser(User user) {
if (user == null) {
System.out.println("null のユーザーは登録できません。");
return;
}
if (users.containsKey(user.id)) {
System.out.println("そのIDはすでに使われています: " + user.id);
return;
}
users.put(user.id, user);
}
Javaここでやっていることを、丁寧に言葉にします。
containsKey(user.id) で「そのIDがすでに登録されていないか」を確認する
重複していたらエラーメッセージを出して登録しない
問題なければ put(user.id, user) で登録する
つまり、
「ID をキーにして、User オブジェクトを Map にしまっている」
という状態です。
ID から User を一瞬で取り出す
findById メソッド
User findById(String id) {
if (id == null || id.isEmpty()) {
return null;
}
return users.get(id);
}
Javausers.get(id) は、
「その ID のユーザーを教えて」
という意味です。
登録されていれば User オブジェクトが返り、
登録されていなければ null が返ります。
ここで感じてほしいのは、
「ID さえ分かれば、ユーザー情報に一瞬でたどり着ける」
という Map の強さです。
List で同じことをやろうとすると、
全ユーザーを先頭から順番に見て、user.id.equals(id) をチェックして…
というループが必要になります。
Map を使うと、それが get(id) 1発になります。
ユーザー情報を更新する
メールアドレスを更新するメソッド
boolean updateEmail(String id, String newEmail) {
User user = findById(id);
if (user == null) {
System.out.println("そのIDのユーザーは存在しません: " + id);
return false;
}
if (newEmail == null || newEmail.isEmpty()) {
System.out.println("メールアドレスは必須です。");
return false;
}
user.email = newEmail;
return true;
}
Javaここで重要なのは、
findById で取り出した user は、
Map の中に入っている User と「同じオブジェクト」だということです。
user.email を書き換えると、
Map の中の User の email も変わります。
「Map に入っているのは“オブジェクトそのもの”ではなく、“オブジェクトへの参照”」
という感覚を、ここでしっかり再確認しておきましょう。
ユーザーを削除する
removeUser メソッド
boolean removeUser(String id) {
if (!users.containsKey(id)) {
System.out.println("そのIDのユーザーは存在しません: " + id);
return false;
}
users.remove(id);
return true;
}
Javaremove(id) は、
「この ID のエントリ(key/value のペア)を Map から消す」
という意味です。
削除したあとに get(id) すると、null が返るようになります。
全ユーザーを一覧表示する
keySet を使って回す
void showAll() {
System.out.println("=== ユーザー一覧 ===");
if (users.isEmpty()) {
System.out.println("ユーザーはまだ登録されていません。");
return;
}
for (String id : users.keySet()) {
User user = users.get(id);
user.show();
}
}
Javaここでやっているのは、
keySet() で「登録されている全てのID」を取り出す
そのIDを使って get(id) で User を取り出すuser.show() で表示する
という流れです。
List のときは「インデックスで回す」
Map のときは「キーの一覧で回す」
という違いが、だいぶ馴染んできたはずです。
3日目のミニアプリ:ユーザー管理
UserDirectory 全体
import java.util.HashMap;
import java.util.Map;
public class UserDirectory {
Map<String, User> users;
UserDirectory() {
users = new HashMap<>();
}
void addUser(User user) {
if (user == null) {
System.out.println("null のユーザーは登録できません。");
return;
}
if (users.containsKey(user.id)) {
System.out.println("そのIDはすでに使われています: " + user.id);
return;
}
users.put(user.id, user);
}
User findById(String id) {
if (id == null || id.isEmpty()) {
return null;
}
return users.get(id);
}
boolean updateEmail(String id, String newEmail) {
User user = findById(id);
if (user == null) {
System.out.println("そのIDのユーザーは存在しません: " + id);
return false;
}
if (newEmail == null || newEmail.isEmpty()) {
System.out.println("メールアドレスは必須です。");
return false;
}
user.email = newEmail;
return true;
}
boolean removeUser(String id) {
if (!users.containsKey(id)) {
System.out.println("そのIDのユーザーは存在しません: " + id);
return false;
}
users.remove(id);
return true;
}
void showAll() {
System.out.println("=== ユーザー一覧 ===");
if (users.isEmpty()) {
System.out.println("ユーザーはまだ登録されていません。");
return;
}
for (String id : users.keySet()) {
User user = users.get(id);
user.show();
}
}
}
JavaMain から使ってみる
public class Main {
public static void main(String[] args) {
UserDirectory dir = new UserDirectory();
dir.addUser(new User("u001", "山田太郎", "yamada@example.com"));
dir.addUser(new User("u002", "佐藤花子", "sato@example.com"));
dir.showAll();
System.out.println("メールアドレスを更新します。");
dir.updateEmail("u001", "yamada_new@example.com");
dir.showAll();
System.out.println("ユーザーを削除します。");
dir.removeUser("u002");
dir.showAll();
System.out.println("存在しないIDで検索してみる。");
User unknown = dir.findById("u999");
System.out.println(unknown); // null が出るはず
}
}
Javaこの Main を眺めてみてください。
ユーザーを登録する
ID からユーザーを探す
メールアドレスを更新する
ユーザーを削除する
一覧表示する
ここには、Map という単語は一切出てきません。
見えているのは、
ユーザー
ユーザーID
ユーザー一覧
という「アプリの世界」だけです。
裏側では、
Map<String, User> が
「ID → User」という key/value の関係を支えています。
3日目で絶対に押さえてほしい本質
今日いちばん大事なのは、
「Map の value に“オブジェクト”を入れると、一気に現実のアプリに近づく」
という感覚です。
Map<String, User> なら「ID → ユーザー」Map<String, Product> なら「商品コード → 商品情報」Map<String, Book> なら「本のID → 本の情報」
というように、
「何かを一意に識別するキー」
「その中身を表すクラス」
をセットで考えると、
Map は一気に強力な武器になります。
そしてもうひとつ。
「Map は“検索のショートカット”」
List でやるとループが必要な検索が、
Map なら get(key) 1発で済む。
この感覚が入っていれば、
4日目以降にやる「Map と List の組み合わせ」や
「設定・キャッシュ・インデックスとしての Map」も、
スッと頭に入ってくるはずです。


