Java の Map には似たようなメソッドがいくつかありますが、
特に混乱しやすいのが getOrDefault() と computeIfAbsent()。
この記事では、それぞれの違いと、実際の使い分け・リストの再利用の仕組みまでを
わかりやすく整理します
結論:目的が違う
| 比較項目 | getOrDefault |
computeIfAbsent |
|---|---|---|
| 目的 | 値を取得するだけ(マップを変更しない) | 値を取得+必要なら生成して登録(マップを変更する) |
| キーが存在しない場合 | デフォルト値を「返す」だけ |
mappingFunction で値を「生成して登録」する |
| 副作用 | なし | あり(マップが更新される) |
| 用途 | 安全に値を読みたいとき | 初期化やキャッシュに使いたいとき |
基本の使い方
getOrDefault:読み取り専用
Map map = new HashMap<>();
map.put("apple", 3);
int value = map.getOrDefault("banana", 0);
System.out.println(value); // 0
System.out.println(map.containsKey("banana")); // false(追加されていない)
🔹 キーが存在しなければデフォルト値を返すだけで、マップ自体は変わりません。
computeIfAbsent:存在しなければ登録もする
Map map = new HashMap<>();
map.put("apple", 3);
int value = map.computeIfAbsent("banana", k -> 10);
System.out.println(value); // 10
System.out.println(map.containsKey("banana")); // true(追加された!)
🔹 キーが存在しない、または値が null の場合のみ mappingFunction が呼ばれます。
よくある使い分けパターン
✅ 1. その場限りの読み取り → getOrDefault
int count = map.getOrDefault("key", 0);
count++;
System.out.println(count); // 1
// map自体は変化しない
✅ 2. 値を初期化して使いたい → computeIfAbsent
マルチマップ(Map>)のような構造で便利です👇
Map> map = new HashMap<>();
map.computeIfAbsent("fruits", k -> new ArrayList<>()).add("apple");
map.computeIfAbsent("fruits", k -> new ArrayList<>()).add("banana");
System.out.println(map);
// {fruits=[apple, banana]}
補足:Listは同じインスタンスが使い回される!
computeIfAbsent() で生成されたリストは、同じキーで呼び出す限り再利用されます。