Skip to content

Commit 0d3306c

Browse files
committed
feat(HashMap): add demo showing hash collisions with a simple custom hash function
What - Added `CollisionInHashMapDemo` class with a `main` method. - Implemented `simpleHash(String key)` function that: - Sums ASCII values of characters. - Returns sum modulo 10 to simulate bucket index in a hash table. - Demonstrated how two different strings (`"ABC"` and `"CBA"`) can produce the same hash → collision. Why - To illustrate the **concept of collisions** in hashing. - Real-world hash-based structures (HashMap, HashSet) must handle collisions because different keys can map to the same bucket index. - Helps understand why Java’s `HashMap` uses both `hashCode()` and `equals()` for proper key management. How 1. `"ABC"`: - A = 65, B = 66, C = 67 - Sum = 198 → 198 % 10 = 8 2. `"CBA"`: - C = 67, B = 66, A = 65 - Sum = 198 → 198 % 10 = 8 3. Both yield hash `8` → **collision** occurs (different keys, same bucket index). 4. Program prints these results to show how collisions arise. Logic Recap - Hash function reduces a large key space into a small set of bucket indexes. - Collisions are inevitable because many keys map into fewer buckets. - Good hashing strategies minimize collisions, but data structures must also resolve them (via chaining or open addressing). Real-Life Application - Explains why a robust `hashCode()` implementation is critical for user-defined objects used in HashMap. - Demonstrates how two different strings can end up in the same bucket. - Prepares foundation for understanding HashMap internals (buckets, linked lists, tree bins). Notes - This demo deliberately uses a weak hash function (`sum % 10`) to force collisions. - In practice, Java’s `hashCode()` + HashMap’s spreading function reduce collisions but cannot eliminate them. - Collision handling ensures map integrity (values not lost, proper key lookup). Signed-off-by: https://github.com/Someshdiwan <[email protected]>
1 parent 592ae96 commit 0d3306c

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import java.util.LinkedList;
2+
import java.util.List;
3+
4+
/**
5+
* Simple custom HashMap-like demo to show chaining using LinkedList.
6+
* Uses a very simple hash function (sum of chars % capacity) to force collisions.
7+
8+
* chaining (LinkedList) inside a custom HashMap so you can see collisions and how entries chain inside a bucket.
9+
*/
10+
11+
public class HashMapChainingDemo {
12+
13+
// Entry to store key-value pairs
14+
static class Entry {
15+
String key;
16+
Integer value;
17+
18+
Entry(String k, Integer v) { key = k; value = v; }
19+
20+
@Override
21+
public String toString() {
22+
return key + "=" + value;
23+
}
24+
}
25+
26+
// Very small hash-table with chaining
27+
static class SimpleHashMap {
28+
private final List<Entry>[] buckets;
29+
30+
@SuppressWarnings("unchecked")
31+
SimpleHashMap(int capacity) {
32+
buckets = new List[capacity];
33+
for (int i = 0; i < capacity; i++) buckets[i] = new LinkedList<>();
34+
}
35+
36+
// Simple hash: sum of characters modulo capacity (intentionally simple to cause collisions)
37+
private int simpleHash(String key) {
38+
int sum = 0;
39+
for (char c : key.toCharArray()) sum += (int) c;
40+
return Math.abs(sum) % buckets.length;
41+
}
42+
43+
// put (insert or update)
44+
public void put(String key, Integer value) {
45+
int idx = simpleHash(key);
46+
List<Entry> bucket = buckets[idx];
47+
for (Entry e : bucket) {
48+
if (e.key.equals(key)) {
49+
e.value = value; // update existing
50+
return;
51+
}
52+
}
53+
bucket.add(new Entry(key, value)); // add new
54+
}
55+
56+
// get
57+
public Integer get(String key) {
58+
int idx = simpleHash(key);
59+
List<Entry> bucket = buckets[idx];
60+
for (Entry e : bucket) {
61+
if (e.key.equals(key)) return e.value;
62+
}
63+
return null;
64+
}
65+
66+
// print all buckets and chains
67+
public void printBuckets() {
68+
System.out.println("Buckets (index -> chain):");
69+
for (int i = 0; i < buckets.length; i++) {
70+
System.out.print(i + " -> ");
71+
if (buckets[i].isEmpty()) {
72+
System.out.println("null");
73+
} else {
74+
System.out.println(buckets[i]);
75+
}
76+
}
77+
}
78+
}
79+
80+
public static void main(String[] args) {
81+
SimpleHashMap map = new SimpleHashMap(5); // small capacity to force collisions
82+
83+
// Keys chosen so some will collide with our simple hash
84+
map.put("ABC", 10);
85+
map.put("CBA", 20); // likely collision with "ABC"
86+
map.put("BAC", 30); // likely collision too
87+
map.put("HELLO", 99);
88+
map.put("OLLEH", 100); // likely collision with HELLO
89+
90+
// print bucket chains
91+
map.printBuckets();
92+
93+
// show get() behavior
94+
System.out.println("\nLookups:");
95+
System.out.println("ABC -> " + map.get("ABC"));
96+
System.out.println("CBA -> " + map.get("CBA"));
97+
System.out.println("BAC -> " + map.get("BAC"));
98+
System.out.println("HELLO -> " + map.get("HELLO"));
99+
System.out.println("OLLEH -> " + map.get("OLLEH"));
100+
}
101+
}
102+
103+
/*
104+
1. Kya dikhaya ja raha hai:
105+
- Ye SimpleHashMap ek chhota demo hai jo chaining (LinkedList) dikhata hai jab collisions hoti hain.
106+
- Hum intentionally simple hash use kar rahe hain (sum of chars % capacity) taaki collisions aasan se ho.
107+
108+
2. Bucket + Chaining:
109+
- Map ke andar ek array hota hai: buckets[]
110+
- Har bucket ek LinkedList (chain) rakhta hai of Entry objects.
111+
- Jab multiple keys same bucket index pe aati hain → woh LinkedList me chain ho jaati hain.
112+
113+
3. put() ka flow:
114+
- key ka hash index nikalte hain (simpleHash).
115+
- us bucket ko traverse karte hain:
116+
- agar key mil jaaye → value update kar do.
117+
- nahi mili → bucket ke end me naya Entry add kar do.
118+
119+
4. get() ka flow:
120+
- key ka index nikal ke us bucket ki LinkedList traverse karte hain.
121+
- matching key milte hi value return kar do.
122+
123+
5. Kyun important hai:
124+
- Real `java.util.HashMap` bhi similar chaining use karta tha (linked list),
125+
aur Java 8+ me jab chain bahut lambi ho jati hai to woh tree me convert kar leta hai.
126+
- Agar sab keys same bucket me chali jaayein (bahut collisions) to search cost O(n)
127+
ho jaata hai — isliye acha hash function zaroori hai.
128+
129+
6. ASCII example (expected, capacity=5):
130+
131+
Suppose simpleHash("ABC") = 3
132+
simpleHash("CBA") = 3
133+
simpleHash("BAC") = 3
134+
135+
Buckets:
136+
0 -> null
137+
1 -> null
138+
2 -> null
139+
3 -> [ABC=10, CBA=20, BAC=30]
140+
4 -> [HELLO=99, OLLEH=100]
141+
142+
7. Quick Recap:
143+
- Chaining = collisions ke liye safe strategy.
144+
- Each bucket holds a linked list of entries.
145+
- get/put average O(1) (if hash distribution is good), worst-case O(n) (if many collisions).
146+
*/

0 commit comments

Comments
 (0)