3
3
import java .util .ArrayList ;
4
4
import java .util .LinkedList ;
5
5
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
+ */
6
26
public class GenericHashMapUsingArrayList <K , V > {
7
27
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
11
30
31
+ /**
32
+ * Constructs a new empty hash map with an initial capacity of 10 buckets.
33
+ */
12
34
public GenericHashMapUsingArrayList () {
13
35
buckets = new ArrayList <>();
14
36
for (int i = 0 ; i < 10 ; i ++) {
@@ -17,6 +39,13 @@ public GenericHashMapUsingArrayList() {
17
39
size = 0 ;
18
40
}
19
41
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
+ */
20
49
public void put (K key , V value ) {
21
50
int hash = Math .abs (key .hashCode () % buckets .size ());
22
51
LinkedList <Node > nodes = buckets .get (hash );
@@ -31,25 +60,36 @@ public void put(K key, V value) {
31
60
nodes .add (new Node (key , value ));
32
61
size ++;
33
62
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 ) {
35
66
reHash ();
36
67
}
37
68
}
38
69
70
+ /**
71
+ * Resizes the hash map by doubling the number of buckets and rehashing existing entries.
72
+ */
39
73
private void reHash () {
40
- ArrayList <LinkedList <Node >> old = buckets ;
74
+ ArrayList <LinkedList <Node >> oldBuckets = buckets ;
41
75
buckets = new ArrayList <>();
42
76
size = 0 ;
43
- for (int i = 0 ; i < old .size () * 2 ; i ++) {
77
+ for (int i = 0 ; i < oldBuckets .size () * 2 ; i ++) {
44
78
buckets .add (new LinkedList <>());
45
79
}
46
- for (LinkedList <Node > nodes : buckets ) {
80
+ for (LinkedList <Node > nodes : oldBuckets ) {
47
81
for (Node node : nodes ) {
48
82
put (node .key , node .val );
49
83
}
50
84
}
51
85
}
52
86
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
+ */
53
93
public V get (K key ) {
54
94
int hash = Math .abs (key .hashCode () % buckets .size ());
55
95
LinkedList <Node > nodes = buckets .get (hash );
@@ -61,6 +101,11 @@ public V get(K key) {
61
101
return null ;
62
102
}
63
103
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
+ */
64
109
public void remove (K key ) {
65
110
int hash = Math .abs (key .hashCode () % buckets .size ());
66
111
LinkedList <Node > nodes = buckets .get (hash );
@@ -72,18 +117,36 @@ public void remove(K key) {
72
117
break ;
73
118
}
74
119
}
75
- nodes .remove (target );
76
- size --;
120
+ if (target != null ) {
121
+ nodes .remove (target );
122
+ size --;
123
+ }
77
124
}
78
125
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
+ */
79
132
public boolean containsKey (K key ) {
80
133
return get (key ) != null ;
81
134
}
82
135
136
+ /**
137
+ * Returns the number of key-value pairs in this map.
138
+ *
139
+ * @return the number of key-value pairs
140
+ */
83
141
public int size () {
84
142
return this .size ;
85
143
}
86
144
145
+ /**
146
+ * Returns a string representation of the map, containing all key-value pairs.
147
+ *
148
+ * @return a string representation of the map
149
+ */
87
150
@ Override
88
151
public String toString () {
89
152
StringBuilder builder = new StringBuilder ();
@@ -96,15 +159,27 @@ public String toString() {
96
159
builder .append (", " );
97
160
}
98
161
}
162
+ // Remove trailing comma and space if there are any elements
163
+ if (builder .length () > 1 ) {
164
+ builder .setLength (builder .length () - 2 );
165
+ }
99
166
builder .append ("}" );
100
167
return builder .toString ();
101
168
}
102
169
170
+ /**
171
+ * A private inner class representing a key-value pair (node) in the hash map.
172
+ */
103
173
private class Node {
104
-
105
174
K key ;
106
175
V val ;
107
176
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
+ */
108
183
Node (K key , V val ) {
109
184
this .key = key ;
110
185
this .val = val ;
0 commit comments