Skip to content

Commit 9e34463

Browse files
committed
Internal Working of IdentityHashMap:
Signed-off-by: https://github.com/Someshdiwan <[email protected]>
1 parent 88f38ac commit 9e34463

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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

Comments
 (0)