|
| 1 | +Internal Working of IdentityHashMap: |
| 2 | + |
| 3 | +1. Key Comparison: |
| 4 | + - Unlike HashMap (which uses `equals()` + `hashCode()`), |
| 5 | + - IdentityHashMap uses **reference equality (==)** to compare keys. |
| 6 | + - Two objects with the same content but different memory addresses are treated as separate keys. |
| 7 | + |
| 8 | +2. Buckets & Hashing: |
| 9 | + - Similar to HashMap, it uses hashing + an internal table (array) to store entries. |
| 10 | + - But during lookup/insert, it checks `(k1 == k2)` instead of `k1.equals(k2)`. |
| 11 | + |
| 12 | +3. Collision Handling: |
| 13 | + - IdentityHashMap is also backed by open addressing (like HashMap). |
| 14 | + - If multiple keys hash to the same bucket, probing is done to find an empty slot. |
| 15 | + |
| 16 | +4. Null Keys & Values: |
| 17 | + - Supports **null keys** and **null values**. |
| 18 | + - Since reference equality works with null, only **one null key** can exist. |
| 19 | + |
| 20 | +5. Performance: |
| 21 | + - Slightly faster lookups in some cases (no equals() calls, just reference comparison). |
| 22 | + - But consumes more memory than HashMap due to open addressing. |
| 23 | + |
| 24 | +6. Use Cases: |
| 25 | + ✔ Object identity tracking (caches, serialization, object pools). |
| 26 | + ✔ When you care about whether two references are the *exact same object*, not just logically equal. |
| 27 | + ✘ Avoid for general-purpose maps where logical equality matters. |
| 28 | + |
| 29 | +────────────────────────────────────────────────────────────── |
| 30 | +📝 ASCII View: |
| 31 | + key1 ("Hello") → [obj#1234] |
| 32 | + key2 ("Hello") → [obj#5678] |
| 33 | + |
| 34 | + HashMap → considers them equal (one entry updated). |
| 35 | + IdentityHM → keeps both separately since 1234 != 5678. |
| 36 | +────────────────────────────────────────────────────────────── |
| 37 | + |
| 38 | + |
| 39 | +████████████████████████████████████████████████████████████████████████ |
| 40 | +⚙️ Extended Theory |
| 41 | +████████████████████████████████████████████████████████████████████████ |
| 42 | + |
| 43 | +1. Comparison Logic: |
| 44 | + - HashMap → `(k1 == null ? k2 == null : k1.equals(k2))`. |
| 45 | + - IdentityHashMap → `(k1 == k2)` only. |
| 46 | + - So even if two objects have the same `hashCode()` and `equals()`, |
| 47 | + they are stored as separate entries if not the same reference. |
| 48 | + |
| 49 | +2. Table Representation: |
| 50 | + - Internally uses an **array of Objects** with alternating slots: |
| 51 | + [Key0, Value0, Key1, Value1, Key2, Value2 ...] |
| 52 | + - This layout is different from HashMap (which stores Nodes/Entries in buckets). |
| 53 | + - Open addressing + linear probing handles collisions. |
| 54 | + |
| 55 | +3. Hashing Behavior: |
| 56 | + - Uses `System.identityHashCode(key)` instead of `key.hashCode()`. |
| 57 | + - `System.identityHashCode()` gives a hash code derived from the |
| 58 | + object’s memory address (not overridable). |
| 59 | + - Ensures uniqueness based on actual object identity. |
| 60 | + |
| 61 | +4. Null Handling: |
| 62 | + - Allows one `null` key because reference equality for `null` is straightforward. |
| 63 | + - Multiple `null` values are allowed. |
| 64 | + |
| 65 | +5. Capacity & Load Factor: |
| 66 | + - Default capacity is 32. |
| 67 | + - Table size always a power of 2. |
| 68 | + - Default load factor = 2/3 (0.67). |
| 69 | + - On exceeding threshold, table grows (resized) with rehashing. |
| 70 | + |
| 71 | +6. Performance: |
| 72 | + - Faster key comparisons (reference check instead of .equals()). |
| 73 | + - Memory overhead due to open addressing. |
| 74 | + - Average time complexity: O(1) for put/get/remove. |
| 75 | + - Worst case: O(n) if too many collisions. |
| 76 | + |
| 77 | +7. Iteration: |
| 78 | + - Iteration order is undefined (like HashMap). |
| 79 | + - Uses backing array directly to iterate over keys/values. |
| 80 | + |
| 81 | +8. Practical Use Cases: |
| 82 | + - Tracking object identities (not content equality). |
| 83 | + - Serialization frameworks (to track already visited objects). |
| 84 | + - Caches where identity is more important than equality. |
| 85 | + - Graph algorithms (e.g., detecting object references). |
| 86 | + |
| 87 | +────────────────────────────────────────────────────────────── |
| 88 | +📝 ASCII Comparison: HashMap vs IdentityHashMap |
| 89 | +────────────────────────────────────────────────────────────── |
| 90 | + |
| 91 | +Suppose: |
| 92 | + key1 = new String("Hello") → obj#1234 |
| 93 | + key2 = new String("Hello") → obj#5678 |
| 94 | + |
| 95 | +HashMap: |
| 96 | + Bucket → { "Hello"=200 } // key1 and key2 merged because equals() true. |
| 97 | + |
| 98 | +IdentityHashMap: |
| 99 | + Table → { obj#1234=100, obj#5678=200 } // kept separately because 1234 != 5678. |
| 100 | + |
| 101 | +────────────────────────────────────────────────────────────── |
| 102 | + |
| 103 | +✔ Key Takeaway: |
| 104 | +- IdentityHashMap is a **special-purpose Map**. |
| 105 | +- Do NOT use it when you expect logical equality of keys. |
| 106 | +- Perfect when reference identity is the only requirement. |
0 commit comments