進歩についていけない焦りを抱えた50代が、

若手のコードを理解できるようになることを目標に、Java7以降を一から学び直す記録です。

2026年3月15日日曜日

【Java進化史 第27回】Java9でSetとMapにも of() が? 〜 なんじゃこりゃ、の続き 〜

前回、こんなコードで手が止まった。
List<String> names = List.of("Tanaka", "Sato", "Suzuki");
List.of()。 変更できないリストを、一行で作る。 なるほど、そういうことか。 ようやく腑に落ちた。
そして今日、また若手のコードを見た。
Set<String> roles = Set.of("ADMIN", "USER", "GUEST");
……また of() だ。 今度は Set か。 Map にもあるんじゃないか、と思って探したら、あった。
Map<String, Integer> scores = Map.of(
    "Tanaka", 90,
    "Sato",   75,
    "Suzuki", 88
);
Map.of() まである。 List、Set、Map。 全部 of() で作れるようになっていた。

■ Java7以前、Setはどう書いていたか

まず、Setを思い出す。
Set<String> roles = new HashSet<>();
roles.add("ADMIN");
roles.add("USER");
roles.add("GUEST");
これが普通だった。 あるいは、こう書く人もいた。
Set<String> roles = new HashSet<>(Arrays.asList("ADMIN", "USER", "GUEST"));
1行にはなる。 だが、new HashSet<>Arrays.asList を渡す。 読めなくはないが、すっきりはしない。

■ Java7以前、Mapはどう書いていたか

Mapはもっと面倒だった。
Map<String, Integer> scores = new HashMap<>();
scores.put("Tanaka", 90);
scores.put("Sato",   75);
scores.put("Suzuki", 88);
putputput。 エントリの数だけ行が増える。 初期データを定義したいだけなのに、 ずいぶん手間がかかった。

■ Java9ではどう書くか

// Set
Set<String> roles = Set.of("ADMIN", "USER", "GUEST");

// Map
Map<String, Integer> scores = Map.of(
    "Tanaka", 90,
    "Sato",   75,
    "Suzuki", 88
);
短い。 意図が見える。

■ SetやMapそのものは変わっていない

念のため確認した。 HashSetHashMap も、使い方は昔のままだ。 SetMap というインターフェースの仕様も変わっていない。 変わったのは一点だけ。 インターフェースに 静的ファクトリメソッド が追加された。 of() は、「こういうSetを作れ」という命令ではなく、 「変更不可のSetを手軽に作るための入口」として追加されたメソッドだ。 昔の new HashSet<>() が消えたわけではない。 選択肢が増えた、ということだ。

■ ひとつだけ、引っかかった

Setを触っていて、気づいた。
Set<String> ng = Set.of("A", "A"); // 実行時例外
重複した値を渡すと、例外が飛ぶ。 Setは重複を許さない。 それはJava7以前から変わっていない。 new HashSet<>()add("A") を2回呼んでも、 黙って無視されるだけだった。 だが Set.of() では、例外になる。 厳しくなった。 渡す前に重複がないか、気をつける必要がある。

■ Mapで10個を超えたら

若手のコードにこんなものがあった。
Map<String, Integer> scores = Map.ofEntries(
    Map.entry("Tanaka",  90),
    Map.entry("Sato",    75),
    Map.entry("Suzuki",  88),
    Map.entry("Yamada",  95),
    Map.entry("Ito",     82)
);
Map.ofEntries()Map.entry()? また知らないものが出てきた。 調べると、Map.of() はキーと値のペアが 10個まで という制限がある。 それを超える場合は Map.ofEntries() を使う、ということらしい。 Map.entry() は、キーと値のペアを1つ作るメソッドだ。 なるほど。 知らないと、また止まるところだった。

■ 3つを並べると

List<String> list        = List.of("A", "B", "C");
Set<String>  set         = Set.of("A", "B", "C");
Map<String, Integer> map = Map.of("A", 1, "B", 2);
List、Set、Map。 全部 of() で作れる。 書き方が統一された。 Java7以前は、それぞれ作り方が違った。 今は、同じ感覚で書ける。

■ 変更できない、という設計

List.of() のときも感じたが、 これらはすべて変更できない。
roles.add("MANAGER");    // 実行時例外
scores.put("Kato", 70);  // 実行時例外
追加も削除も、できない。 Java7以前の感覚だと、 「とりあえず new HashMap<>()」だった。 変更するかどうかは、後で考えればいい。 だが若手は最初から変更しない前提で書いている。 設計の向きが、少し違う。

■ なんじゃこりゃ、は続く



0 件のコメント:

コメントを投稿

【Java進化史 第27回】Java9でSetとMapにも of() が? 〜 なんじゃこりゃ、の続き 〜

前回、こんなコードで手が止まった。 List<String> names = List.of("Tanaka", "Sato", "Suzuki"); List.of() 。 変更できないリストを、一...