Java 逆引き集 | IdentityHashMap(== でキー比較) — 特殊用途

Java Java
スポンサーリンク

IdentityHashMap(== でキー比較) — 特殊用途

IdentityHashMap は Java の特殊な Map 実装で、キーの比較に equals() ではなく ==(参照同一性) を使います。
初心者が理解すべきポイントは「同じ内容でも別インスタンスなら別キー扱いになる」ということです。


特徴

  • キー比較: == を使う → 参照が同じオブジェクトだけ同一キーとみなす。
  • 用途:
    • オブジェクトの「実体そのもの」を区別したいとき。
    • シリアライズや内部処理で「同一インスタンスかどうか」を判定したいとき。
  • 一般用途には不向き: 普通の辞書用途なら HashMap を使うべき。
  • サイズ: 内部的に配列ベースで軽量。

基本コード例

1. HashMap との違い

import java.util.*;

public class IdentityHashMapDemo {
    public static void main(String[] args) {
        Map<String, String> hashMap = new HashMap<>();
        Map<String, String> identityMap = new IdentityHashMap<>();

        String a1 = new String("key");
        String a2 = new String("key"); // 内容は同じだが別インスタンス

        hashMap.put(a1, "value1");
        hashMap.put(a2, "value2");

        identityMap.put(a1, "value1");
        identityMap.put(a2, "value2");

        System.out.println("HashMap: " + hashMap);       // {key=value2} (equalsで同一扱い)
        System.out.println("IdentityHashMap: " + identityMap); // {key=value1, key=value2} (==で別扱い)
    }
}
Java

👉 ポイント: HashMap は内容が同じなら上書き、IdentityHashMap は別インスタンスなら別キー。


2. 同一インスタンスなら同じキー

IdentityHashMap<Object, String> map = new IdentityHashMap<>();

Object obj = new Object();
map.put(obj, "data");

System.out.println(map.get(obj)); // data
System.out.println(map.get(new Object())); // null (別インスタンスなので一致しない)
Java

よく使う場面

  • シリアライズ処理: オブジェクト参照を追跡し、同じインスタンスを複数回出力しないようにする。
  • 内部キャッシュ: 「同じ内容でも別インスタンスなら別物」として扱う必要がある場合。
  • 特殊用途: フレームワークやライブラリの内部処理で利用されることが多い。

例題で練習

例題1: インスタンスごとの識別

IdentityHashMap<Object, Integer> ids = new IdentityHashMap<>();

Object o1 = new Object();
Object o2 = new Object();

ids.put(o1, 100);
ids.put(o2, 200);

System.out.println(ids.get(o1)); // 100
System.out.println(ids.get(o2)); // 200
Java

👉 同じ equals を持つオブジェクトでも、インスタンスが違えば別キー。


例題2: シリアライズ時の参照追跡

IdentityHashMap<Object, Integer> seen = new IdentityHashMap<>();
Object obj = new Object();

if (!seen.containsKey(obj)) {
    seen.put(obj, 1); // 初回出現
} else {
    System.out.println("既に出現済み");
}
Java

👉 同じインスタンスを複数回処理しないようにする用途。


テンプレート集

宣言

Map<KeyType, ValueType> map = new IdentityHashMap<>();
Java

追加

map.put(key, value);
Java

取得

ValueType v = map.get(key); // == で一致するキーのみ取得可能
Java

存在確認

boolean exists = map.containsKey(key);
Java

実務でのコツ

  • 通常用途には使わない: 普通の辞書は HashMap。IdentityHashMap は特殊ケース専用。
  • equals/hashCode 無視: 内容比較ではなく参照比較なので、混乱しやすい。
  • フレームワーク内部でよく使われる: 開発者が直接使うことは少ないが、仕組みを理解しておくと役立つ。
  • GC と関係なし: WeakHashMap のように GC で消えるわけではない。

まとめ

  • IdentityHashMap は「==」でキー比較する特殊な Map。
  • 同じ内容でも別インスタンスなら別キー扱い。
  • シリアライズや内部処理など特殊用途に使われる。

👉 練習課題として「同じ文字列内容でもインスタンスごとに別の値を保持する」プログラムを書いてみると、IdentityHashMap の特徴が体感できます。

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