HASH COLLISIONS
It is possible that two distinct keys can generate the same hash values. What are we going to do we cannot store two items at the same index. This is called a collision.
There are 2 ways to handle collisions
One way is to have each cell in our array point to a linked list. So we are not going to store value in the array itself. We are going to store them in linked lists. If we have a collision we add the item at the end of the linked list. This is what we call CHAINING because we are chaining these items.
Another solution is to find a different slot/bucket for storing the second value. This is what we call OPEN ADDRESSING because we are finding a new address to store the second value. There are different Algorithms for it Like Linear Probing, Quadratic Probing, Double Hashing etc. Open Addressing is not the most feasible solution according to me. I personally like and use Chaining.
CHAINING IMPLEMENTATION IN JAVA
Let's start with understanding the implementation
// Create a HashTable Class
// In this class we should have methods like
// put(key,value)
// get(key) : value takes key as input and returns a value
// remove(key) remove takes key and removes corresponding variable
// keys:int value:String
// Collision: Chaining instead of storing k:v in array cell we store them in Linked Lists
// So we should create a private class called Entry which wraps key:value pair
// LinkedList<Entry>[]
EXPLAINING THE DATA STRUCTURE
we have an array of Linked Lists which have generic type Entry which has key and value wrapped in it of initial size 5.
[ LL<Entry1>, LL<Entry2>, LL<Entry3>, LL<Entry4>, LL<Entry5> ]
public void put(int key, String value){...}
1.> Hash () provides an index to enter the element.
2.> Check if that index is null if true add at entries[index] an instance to the Linked List class.
3.> Check for duplicate Key by iterating over Linked List.
4.> If a new key is == to the already present key update the value and return because we don't want to update the new Entry at the end.
import java.util.LinkedList;
public class hashTable {
private class Entry{
private int key;
private String value;
public Entry(int key,String value){
this.value=value;
this.key=key;
}
}
private LinkedList<Entry>[] entries =new LinkedList[5];
public void put (int key,String value){
var index = hash(key);
if(entries[index]==null)
entries[index]= new LinkedList<>();
for(var entry:entries[index]){
if(entry.key==key){
entry.value =value;
return;
}
}
entries[index].addLast(new Entry(key, value));
}
public String get (int key){
var index =hash(key);
if (entries[index]!= null) {
for (var entry : entries[index]) {
if (entry.key == key)
return entry.value;
}
}
return null;
}
public void remove(int key){
var index = hash(key);
if (entries[index]== null)
throw new IllegalStateException();
for(var entry:entries[index]){
if(entry.key==key){
entries[index].remove(entry);
return ;
}
}
throw new IllegalStateException();
}
private int hash(int key){
return key% entries.length;
}
public static void main(String[] args) {
hashTable hash =new hashTable();
hash.put(6,"A"); //1 index
hash.put(8,"B"); //3 index
hash.put(11,"C"); //1 index collision
hash.put(6,"A+");
System.out.println(hash.get(6));
hash.remove(6);
}
}