Skip to content

Commit 30c9b64

Browse files
committed
Internal Working of LinkedHashMap in Java
Signed-off-by: https://github.com/Someshdiwan <[email protected]>
1 parent 9c36860 commit 30c9b64

File tree

6 files changed

+643
-0
lines changed

6 files changed

+643
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
HashMap and LinkedHashMap so you clearly see why one preserves order and the other doesn’t.
2+
3+
4+
5+
🔹 HashMap (No Order Guarantee)
6+
7+
Keys inserted: "Shubham", "Bob", "Akshit"
8+
9+
Internal Structure (buckets):
10+
11+
Bucket[0] : null
12+
Bucket[1] : ("Bob" -> 80)
13+
Bucket[2] : ("Akshit" -> 78)
14+
Bucket[3] : ("Shubham" -> 92)
15+
Bucket[4] : null
16+
...
17+
Bucket[15]: null
18+
19+
Iteration → Goes bucket by bucket:
20+
Output may look like: {Akshit=78, Shubham=92, Bob=80}
21+
22+
❌ Order is NOT insertion-based
23+
❌ Order is NOT access-based
24+
25+
• Why unordered? Because keys are placed in buckets based on hashCode % capacity.
26+
• Iteration just walks bucket array → so order looks random.
27+
28+
29+
30+
🔹 LinkedHashMap (accessOrder = false → Insertion Order)
31+
32+
Keys inserted: "Orange", "Apple", "Guava"
33+
34+
Doubly Linked List (insertion order maintained):
35+
36+
HEAD <-> Orange(10) <-> Apple(20) <-> Guava(13) <-> TAIL
37+
38+
Iteration output:
39+
Orange=10
40+
Apple=20
41+
Guava=13
42+
43+
• Preserves insertion order by default.
44+
45+
46+
47+
🔹 LinkedHashMap (accessOrder = true → Access Order)
48+
49+
Keys inserted: "Orange", "Apple", "Guava"
50+
Access pattern: get("Apple"), get("Orange"), get("Guava")
51+
52+
Doubly Linked List (reordered on access):
53+
54+
HEAD <-> Apple(20) <-> Orange(10) <-> Guava(13) <-> TAIL
55+
56+
Iteration output:
57+
Apple=20
58+
Orange=10
59+
Guava=13
60+
61+
• Every time an entry is accessed, it is moved to the end.
62+
• Newest (most recently accessed) items go at the tail.
63+
• Oldest (least accessed) stay near the head.
64+
65+
This mechanism is exactly how LRU Cache is built using LinkedHashMap.
66+
67+
68+
69+
⚡ Quick Recap:
70+
• HashMap → Bucket-based, order = unpredictable.
71+
• LinkedHashMap (Insertion Order) → Order of insertion is preserved.
72+
• LinkedHashMap (Access Order) → Reorders entries based on access (like LRU).
73+
74+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
Internal Working of LinkedHashMap in Java
2+
3+
Introduction:
4+
5+
- `LinkedHashMap` Java Collections Framework ka ek class hai jo `HashMap` ko extend karta hai.
6+
- Yeh **key-value pairs store karta hai** bilkul HashMap ki tarah,
7+
lekin saath hi ek **doubly-linked list** maintain karta hai jo order preserve karti hai.
8+
- Isliye isme fast access ke saath insertion order ya access order maintain karna possible hai.
9+
10+
---
11+
12+
1. Underlying Data Structure:
13+
- Internally, `LinkedHashMap` uses:
14+
1. **Hash Table** → Fast access ke liye (O(1) average for put/get).
15+
2. **Doubly Linked List** → Order preserve karne ke liye.
16+
17+
- Har ek entry ek special class hoti hai:
18+
19+
static class Entry<K,V> extends HashMap.Node<K,V> {
20+
Entry<K,V> before, after;
21+
}
22+
- `before` and `after` pointers ek **linked list chain** banate hain.
23+
24+
---
25+
26+
2. Order Preservation:
27+
28+
- `LinkedHashMap` do tarah ka order maintain kar sakta hai:
29+
1. **Insertion Order (default)**: Jo key pehle daali gayi, woh pehle traverse hogi.
30+
2. **Access Order (optional)**: Agar constructor me `accessOrder = true` pass karo,
31+
toh har get/put operation ke baad woh entry list ke end me shift ho jaati hai.
32+
33+
Example:
34+
35+
LinkedHashMap<Integer, String> map = new LinkedHashMap<>(16, 0.75f, true);
36+
37+
Yahan `true` matlab access order maintain karna.
38+
39+
---
40+
41+
3. Internal Working Steps:
42+
43+
### put(K,V)
44+
1. Key ka `hashCode()` calculate hota hai → bucket index milta hai.
45+
2. Agar key pehle se exist karta hai → value overwrite hoti hai.
46+
3. Agar new key hai → ek naya `Entry` banega.
47+
- Entry hash table me insert hota hai (HashMap jaisa).
48+
- Saath hi entry doubly linked list me bhi add hota hai (order preserve karne ke liye).
49+
50+
---
51+
52+
### get(K)
53+
1. Key ka `hashCode()` calculate karke bucket search hoti hai.
54+
2. Agar entry milti hai aur map access-order mode me hai:
55+
- Entry ko linked list ke end me shift kar diya jata hai.
56+
3. Value return hoti hai.
57+
58+
---
59+
60+
4. Complexity
61+
-------------
62+
- `put()`, `get()`, `remove()` → O(1) average time (HashMap ki tarah).
63+
- Order maintain karne ki wajah se thoda extra overhead lagta hai.
64+
65+
---
66+
67+
5. ASCII Diagram:
68+
69+
Insertion Order Example:
70+
71+
```
72+
Hash Table (buckets):
73+
[ ] [ ] [ (1,A) ] [ (2,B) ] [ (3,C) ] ...
74+
75+
Linked List (order chain):
76+
Head → (1,A) <-> (2,B) <-> (3,C) ← Tail
77+
```
78+
79+
Access Order Example (agar accessOrder = true):
80+
81+
- Suppose get(1) call kiya:
82+
```
83+
Before: Head → (1,A) <-> (2,B) <-> (3,C)
84+
After: Head → (2,B) <-> (3,C) <-> (1,A)
85+
```
86+
87+
---
88+
89+
6. Advantages
90+
-------------
91+
- Predictable iteration order (HashMap ka yeh drawback fix karta hai).
92+
- Useful for building **LRU Cache** (Least Recently Used cache).
93+
94+
---
95+
96+
7. Disadvantages
97+
----------------
98+
- Thoda zyada memory use karta hai (doubly linked list pointers ke wajah se).
99+
- Thoda performance overhead hota hai as compared to plain HashMap.
100+
101+
---
102+
103+
8. Common Use Cases
104+
-------------------
105+
- LRU Cache implementation.
106+
- Jab order of insertion ya access preserve karna zaroori ho.
107+
- Predictable iteration chahiye fast lookup ke saath.
108+
109+
---
110+
111+
Summary:
112+
- `LinkedHashMap = HashMap + LinkedList`
113+
- Provides O(1) put/get/remove operations.
114+
- Maintains order (insertion or access).
115+
- Ideal for caches, predictable iteration, aur jab HashMap ka unordered behavior avoid karna ho.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
📌 Internal Working of LinkedHashMap (with accessOrder & eviction)
2+
=================================================================
3+
4+
1. Core Formula Recap
5+
---------------------
6+
7+
- **Threshold** = `capacity × loadFactor`
8+
- **Rehash Trigger**: when `size > threshold`
9+
- **Access Order**:
10+
- If `accessOrder = false` → Order = Insertion order
11+
- If `accessOrder = true` → Order = Access order (recently accessed node is moved to the end)
12+
- **Eviction Rule (via removeEldestEntry)**:
13+
- Called **after each put()**.
14+
- If `true`, eldest entry (head of linked list) is removed.
15+
16+
---
17+
18+
2. ASCII Flow: Insertion Order (Default)
19+
----------------------------------------
20+
(accessOrder = false)
21+
22+
```
23+
Put(1,A) → 1:A
24+
Put(2,B) → 1:A → 2:B
25+
Put(3,C) → 1:A → 2:B → 3:C
26+
```
27+
Iteration → `[1:A, 2:B, 3:C]`
28+
29+
---
30+
31+
3. ASCII Flow: Access Order (accessOrder = true)
32+
------------------------------------------------
33+
34+
```
35+
Initial: 1:A → 2:B → 3:C
36+
37+
Access(1) → Move 1:A to end
38+
Result: 2:B → 3:C → 1:A
39+
40+
Access(2) → Move 2:B to end
41+
Result: 3:C → 1:A → 2:B
42+
```
43+
44+
Iteration → in order of **most recent access**.
45+
46+
---
47+
48+
4. ASCII Flow: With Eviction (removeEldestEntry)
49+
------------------------------------------------
50+
51+
Suppose max size = 3 (`removeEldestEntry()` removes if size > 3)
52+
53+
```
54+
Insert(1:A) → 1:A
55+
Insert(2:B) → 1:A → 2:B
56+
Insert(3:C) → 1:A → 2:B → 3:C
57+
Insert(4:D) → capacity exceeded → remove eldest (1:A)
58+
Result: 2:B → 3:C → 4:D
59+
```
60+
61+
If accessOrder = true:
62+
```
63+
Initial: 2:B → 3:C → 4:D
64+
Access(2) → Move 2:B to end
65+
Result: 3:C → 4:D → 2:B
66+
Insert(5:E) → remove eldest (3:C)
67+
Result: 4:D → 2:B → 5:E
68+
```
69+
70+
---
71+
72+
5. Internal Structure
73+
---------------------
74+
75+
LinkedHashMap = HashMap + Doubly Linked List.
76+
77+
```
78+
Buckets (Hash Table):
79+
0 1 2 ...
80+
[ ] [ ] [ ] ...
81+
82+
Linked List (Order Maintenance):
83+
Head ↔ Node1 ↔ Node2 ↔ Node3 ↔ Tail
84+
```
85+
86+
- Each entry stores:
87+
- `key`
88+
- `value`
89+
- `hash`
90+
- `next` (for bucket chain)
91+
- `before` and `after` (for doubly linked list)
92+
93+
---
94+
95+
6. Practical Formula Examples
96+
------------------------------
97+
98+
- **Threshold** = `capacity × loadFactor`
99+
- Example: capacity = 16, loadFactor = 0.75 → threshold = 12
100+
→ Rehash after 13th element.
101+
102+
- **Access Order Movement**:
103+
- On every `get(key)` or `put(key,value)` (when key exists):
104+
- Node is removed from its current linked list position.
105+
- Node is reinserted at **tail** of linked list.
106+
107+
- **Eviction**:
108+
- After every `put()`, `removeEldestEntry()` runs:
109+
```java
110+
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
111+
return size() > MAX_ALLOWED;
112+
}
113+
```
114+
115+
---
116+
117+
🔑 Quick Recap
118+
--------------
119+
- **Insertion Order** (default): Iterates in the order elements were put.
120+
- **Access Order** (`true`): Recently accessed elements move to tail → Useful for **LRU caching**.
121+
- **removeEldestEntry()**: Automatic eviction rule (e.g., max cache size).
122+
- **Threshold** controls rehashing.
123+
124+
👉 `LinkedHashMap` = predictable iteration + ability to implement efficient caches.

0 commit comments

Comments
 (0)