Below is the best Java interview-level explanation + full custom HashMap implementation written in clean, production-style code.
I will give you:
-
Concept explanation (what interviewer expects)
-
Key points to mention verbally
-
Full working implementation of CustomHashMap<K, V>
-
Example usage
✅ 1. Concept Interviewers Expect
A custom HashMap usually demonstrates:
-
Array of buckets
-
Each bucket stores linked list (or tree – but interview usually accepts list)
-
put(key, value) -
get(key) -
remove(key)(optional but good) -
Handling hash collision
-
Handling resize / rehash
You do NOT need to implement TreeNodes like JDK HashMap unless asked.
✅ 2. Key points to say in an interview
If asked verbally:
“My custom HashMap uses an array of buckets.
Each bucket holds a linked list of entries.
Key is converted to index by(hash & (capacity - 1)).
Collision is handled using chaining.
When load factor exceeds threshold, I resize the array and rehash all entries.”
This is enough to pass.
✅ 3. Full Implementation — CustomHashMap<K, V>
✔ Clean
✔ Easy to explain
✔ Close to how JDK HashMap works
public class CustomHashMap<K, V> {
// Node inside each bucket (LinkedList)
static class Entry<K, V> {
K key;
V value;
Entry<K, V> next;
Entry(K key, V value, Entry<K, V> next) {
this.key = key;
this.value = value;
this.next = next;
}
}
private Entry<K, V>[] table; // bucket array
private int capacity = 16; // default size
private float loadFactor = 0.75f;
private int size = 0; // current number of entries
public CustomHashMap() {
table = new Entry[capacity];
}
private int hash(K key) {
return key == null ? 0 : (key.hashCode() & (capacity - 1));
}
public void put(K key, V value) {
int index = hash(key);
Entry<K, V> head = table[index];
// Check if key already exists -> update it
Entry<K, V> curr = head;
while (curr != null) {
if ((key == null && curr.key == null) || (key != null && key.equals(curr.key))) {
curr.value = value; // update
return;
}
curr = curr.next;
}
// Insert new entry at the head of list
Entry<K, V> newEntry = new Entry<>(key, value, head);
table[index] = newEntry;
size++;
// Resize check
if ((1.0 * size) / capacity >= loadFactor) {
resize();
}
}
public V get(K key) {
int index = hash(key);
Entry<K, V> curr = table[index];
while (curr != null) {
if ((key == null && curr.key == null) || (key != null && key.equals(curr.key))) {
return curr.value;
}
curr = curr.next;
}
return null; // not found
}
public V remove(K key) {
int index = hash(key);
Entry<K, V> curr = table[index];
Entry<K, V> prev = null;
while (curr != null) {
if ((key == null && curr.key == null) || (key != null && key.equals(curr.key))) {
// delete node
if (prev == null) {
table[index] = curr.next;
} else {
prev.next = curr.next;
}
size--;
return curr.value;
}
prev = curr;
curr = curr.next;
}
return null;
}
// Resize: Double capacity and rehash all entries
private void resize() {
int oldCapacity = capacity;
capacity = capacity * 2;
Entry<K, V>[] oldTable = table;
table = new Entry[capacity];
size = 0;
for (int i = 0; i < oldCapacity; i++) {
Entry<K, V> entry = oldTable[i];
while (entry != null) {
put(entry.key, entry.value); // rehash
entry = entry.next;
}
}
}
public int size() {
return size;
}
}
✅ 4. Example Usage
public class Main {
public static void main(String[] args) {
CustomHashMap<String, Integer> map = new CustomHashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
System.out.println(map.get("B")); // 2
map.put("B", 20);
System.out.println(map.get("B")); // 20
map.remove("A");
System.out.println(map.size()); // 2
}
}
Want an even more advanced version?
I can also give you:
-
Open addressing (linear probing) HashMap
-
HashMap with TreeBins like JDK8
-
ConcurrentHashMap simplified version
-
Memory-efficient hash map with primitive arrays (Agrona-style)
Tell me which version you'd want next.
No comments:
Post a Comment