Implementing HashTable in Java
Hash table in the form similar to this structure
0 node -> node -> node
1 node -> node
2 null
3 node
4 node -> node
5 null
In the above, it means there is an ArrayList of size 6, as you can see there are 6 linked lists.
Each element of the ArrayList stores the head node of the list. Each linked list represents a bucket for storage.
A node in the linked list consists of a Key and a Value.
Adding a new node: Locate the bucket -> Insert the new node into the linked list
Locate the bucket: Get the hashCode of the Key -> Calculate the module of the hashCode by the size of the ArrayList -> Then use the result as the index to get the bucket(head node of a linked list) from the ArrayList
Locate the bucket: buckets.get(hashCode % size)
When the number of total key-value pair goes beyond the threshold, in this case 70% of the allocated ArrayList size, then double the ArrayList size and balance the data.
The code for implementing a hash table in Java.
import java.util.ArrayList; /** * * @paramK represents Key object * @param V represents Value object */ public class HMap { private class Node { public K k; public V v; public Node next; public Node(K k, V v) { this.k = k; this.v = v; } } private static double THRESHOLD = 0.7; private int size; private int allocationSize; private ArrayList > buckets = new ArrayList<>(); public HMap() { size = 0; allocationSize = 2; allocateSize(allocationSize); } public int size() { return this.size; } public void clear() { this.buckets.clear(); size = 0; } public boolean isEmpty() { return size == 0; } private void allocateSize(int size) { for (int i=0; i< size; i++) { buckets.add(null); } } private boolean hasExceedThreshold() { return (1.0*size) / allocationSize >= THRESHOLD; } private int getBucketIndex(K k) { int hashNum = k.hashCode(); int bucketIndex = hashNum % allocationSize; return bucketIndex; } private void balanceData() { // save all of the existing node in an arraylist ArrayList nodes = new ArrayList<>(); for (int i=0; i = THRESHOLD of the allocation size if (hasExceedThreshold()) { allocateSize(allocationSize); allocationSize = allocationSize * 2; balanceData(); } } public V get(K k) { // find the bucket index int bucketIndex = getBucketIndex(k); Node head = buckets.get(bucketIndex); if (head == null) return null; Node cur = head; while (cur != null) { if (cur.k.equals(k)) { return (V) cur.v; } cur = cur.next; } return null; } public void remove(K k) { int bucketIndex = getBucketIndex(k); Node head = buckets.get(bucketIndex); if (head == null) return; if (head.k.equals(k)) { buckets.set(bucketIndex, head.next); size--; return; } Node prev = head; Node cur = prev.next; while (cur != null) { if (cur.k.equals(k)) { prev.next = cur.next; size--; return; } prev = cur; cur = cur.next; } } public static void main(String args[]) { HMap hMap = new HMap<>(); hMap.add(1, "One"); hMap.add(2, "Two"); hMap.add(3, "Three"); hMap.add(4, "Four"); hMap.add(5, "Five"); System.out.println("Expected Size: " + 5 + ", Actual: " + hMap.size()); hMap.remove(4); System.out.println("Expected Size: " + 4 + ", Actual: " + hMap.size()); System.out.println("Expected: One, Actual: " + hMap.get(1)); System.out.println("Expected: Two, Actual: " + hMap.get(2)); System.out.println("Expected: Three, Actual: " + hMap.get(3)); System.out.println("Expected: null, Actual: " + hMap.get(4)); System.out.println("Expected: Five, Actual: " + hMap.get(5)); hMap.add(4, "Four"); hMap.add(4, "Fourr"); System.out.println("Expected Size: " + 5 + ", Actual: " + hMap.size()); System.out.println("Expected: Fourr, Actual: " + hMap.get(4)); hMap.clear(); System.out.println("Expected Size: " + 0 + ", Actual: " + hMap.size()); System.out.println("Expected isEmpty: true, Actual isEmpty: " + hMap.isEmpty()); } }
Search within Codexpedia
Search the entire web