33import java .util .ArrayList ;
44import java .util .LinkedList ;
55
6+ /**
7+ * A generic implementation of a hash map using an array list of linked lists for collision resolution.
8+ * This class allows storage of key-value pairs with average-case constant time complexity for insertion,
9+ * deletion, and retrieval operations.
10+ *
11+ * <p>
12+ * The hash map uses separate chaining to handle collisions. Each bucket in the hash map is represented
13+ * by a linked list that holds nodes containing key-value pairs. When multiple keys hash to the same index,
14+ * they are stored in the same linked list.
15+ * </p>
16+ *
17+ * <p>
18+ * The hash map automatically resizes itself when the load factor exceeds 0.5. The load factor is defined
19+ * as the ratio of the number of entries to the number of buckets. When resizing occurs, all existing entries
20+ * are rehashed and inserted into the new buckets.
21+ * </p>
22+ *
23+ * @param <K> the type of keys maintained by this hash map
24+ * @param <V> the type of mapped values
25+ */
626public class GenericHashMapUsingArrayList <K , V > {
727
8- ArrayList <LinkedList <Node >> buckets ;
9- private float lf = 0.5f ;
10- private int size ;
28+ private ArrayList <LinkedList <Node >> buckets ; // Array list of buckets (linked lists)
29+ private int size ; // Number of key-value pairs in the hash map
1130
31+ /**
32+ * Constructs a new empty hash map with an initial capacity of 10 buckets.
33+ */
1234 public GenericHashMapUsingArrayList () {
1335 buckets = new ArrayList <>();
1436 for (int i = 0 ; i < 10 ; i ++) {
@@ -17,6 +39,13 @@ public GenericHashMapUsingArrayList() {
1739 size = 0 ;
1840 }
1941
42+ /**
43+ * Associates the specified value with the specified key in this map.
44+ * If the map previously contained a mapping for the key, the old value is replaced.
45+ *
46+ * @param key the key with which the specified value is to be associated
47+ * @param value the value to be associated with the specified key
48+ */
2049 public void put (K key , V value ) {
2150 int hash = Math .abs (key .hashCode () % buckets .size ());
2251 LinkedList <Node > nodes = buckets .get (hash );
@@ -31,25 +60,36 @@ public void put(K key, V value) {
3160 nodes .add (new Node (key , value ));
3261 size ++;
3362
34- if ((float ) size / buckets .size () > lf ) {
63+ // Load factor threshold for resizing
64+ float loadFactorThreshold = 0.5f ;
65+ if ((float ) size / buckets .size () > loadFactorThreshold ) {
3566 reHash ();
3667 }
3768 }
3869
70+ /**
71+ * Resizes the hash map by doubling the number of buckets and rehashing existing entries.
72+ */
3973 private void reHash () {
40- ArrayList <LinkedList <Node >> old = buckets ;
74+ ArrayList <LinkedList <Node >> oldBuckets = buckets ;
4175 buckets = new ArrayList <>();
4276 size = 0 ;
43- for (int i = 0 ; i < old .size () * 2 ; i ++) {
77+ for (int i = 0 ; i < oldBuckets .size () * 2 ; i ++) {
4478 buckets .add (new LinkedList <>());
4579 }
46- for (LinkedList <Node > nodes : buckets ) {
80+ for (LinkedList <Node > nodes : oldBuckets ) {
4781 for (Node node : nodes ) {
4882 put (node .key , node .val );
4983 }
5084 }
5185 }
5286
87+ /**
88+ * Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
89+ *
90+ * @param key the key whose associated value is to be returned
91+ * @return the value associated with the specified key, or null if no mapping exists
92+ */
5393 public V get (K key ) {
5494 int hash = Math .abs (key .hashCode () % buckets .size ());
5595 LinkedList <Node > nodes = buckets .get (hash );
@@ -61,6 +101,11 @@ public V get(K key) {
61101 return null ;
62102 }
63103
104+ /**
105+ * Removes the mapping for the specified key from this map if present.
106+ *
107+ * @param key the key whose mapping is to be removed from the map
108+ */
64109 public void remove (K key ) {
65110 int hash = Math .abs (key .hashCode () % buckets .size ());
66111 LinkedList <Node > nodes = buckets .get (hash );
@@ -72,18 +117,36 @@ public void remove(K key) {
72117 break ;
73118 }
74119 }
75- nodes .remove (target );
76- size --;
120+ if (target != null ) {
121+ nodes .remove (target );
122+ size --;
123+ }
77124 }
78125
126+ /**
127+ * Returns true if this map contains a mapping for the specified key.
128+ *
129+ * @param key the key whose presence in this map is to be tested
130+ * @return true if this map contains a mapping for the specified key
131+ */
79132 public boolean containsKey (K key ) {
80133 return get (key ) != null ;
81134 }
82135
136+ /**
137+ * Returns the number of key-value pairs in this map.
138+ *
139+ * @return the number of key-value pairs
140+ */
83141 public int size () {
84142 return this .size ;
85143 }
86144
145+ /**
146+ * Returns a string representation of the map, containing all key-value pairs.
147+ *
148+ * @return a string representation of the map
149+ */
87150 @ Override
88151 public String toString () {
89152 StringBuilder builder = new StringBuilder ();
@@ -96,15 +159,27 @@ public String toString() {
96159 builder .append (", " );
97160 }
98161 }
162+ // Remove trailing comma and space if there are any elements
163+ if (builder .length () > 1 ) {
164+ builder .setLength (builder .length () - 2 );
165+ }
99166 builder .append ("}" );
100167 return builder .toString ();
101168 }
102169
170+ /**
171+ * A private inner class representing a key-value pair (node) in the hash map.
172+ */
103173 private class Node {
104-
105174 K key ;
106175 V val ;
107176
177+ /**
178+ * Constructs a new Node with the specified key and value.
179+ *
180+ * @param key the key of the key-value pair
181+ * @param val the value of the key-value pair
182+ */
108183 Node (K key , V val ) {
109184 this .key = key ;
110185 this .val = val ;
0 commit comments