Putting Values
As our second main functionality, we will implement the ability to insert values into a MyHashMap based on their corresponding key.
However, before we implement such a put method, we need to create a couple more helper methods that will simplify our implementation.
insert Method
Since we are using SimpleEntry<K, V> objects to represent a key/value pair, we want to insert a SimpleEntry<K, V> object in our hashtable. For this, we will implement a private insert helper method that takes a SimpleEntry<K, V> entry as a parameter and behaves as follows:
Gets the
keyfor theentryusing itsgetKey()method and calculates the appropriateindexas in Step 1 of thefindmethod from Part 2 of the lab.Gets the appropriate
LinkedListfrom thehashtableusing theindexcalculated in Step 1.Adds the given
entryto theLinkedListfound in Step 2.
Here, we assume that the key of the given SimpleEntry<K, V> is not already in the hashtable.
resize Method
As we insert more and more key/value pairs into our hashtable, we increase the likelihood that two keys collide by having the same index into the hashtable’s bucket array based on their (different) hashCodes. Since we are using chaining to handle collisions, the runtime of our methods will increase as the number of collisions also increases.
To minimize the risk of collisions, we will resize the hashtable once the size of the MyHashMap reaches a predetermined percentage of the number of buckets in the hashtable’s bucket array. Implement a private resize method that takes no parameters, returns nothing, and behaves as follows:
Save the old
hashtableas a different variableCreate a new array for the
hashtableinstance variable using the providedcreateTablemethod, passing in double thelengthof the oldhashtableso that the size is at least doubled (n.b., it will actually be the next prime number after double the old length).Iterate through every
SimpleEntry<K, V>in everyLinkedListin the oldhashtableand callputto re-hash and re-insert thekey/valuepairs.
put Method
In Java, inserting a new key/value pair is accomplished through the method:
public V put(K key, V value)
If the key was already in the MyHashMap, then the method returns the previous value stored for that key, else it returns null. The pseudocode for this method is:
Use the
findmethod developed above to look up whetherkeywas already in theMyHashMapIf
findreturns aSimpleEntry<K, V>object becausekeywas already in theHashMap, save the previous value from theSimpleEntry<K, V>and change the value to thevaluepassed into the method usingSimpleEntry’ssetValue(value)methodIf
findinstead returnednullbecausekeywas not already in theHashMap, then we need to create a newSimpleEntry<K, V>storing the givenkeyandvaluethat were arguments to theputmethod. Call theinserthelper method described above, and increase thesizeof theMyHashMapsince a newkeywas inserted.Next, check whether we need to resize the
hashtableso that we can minimize the risk of collisions. This should occur whenever thesizeof theMyHashMapis greater thanLOAD_FACTORtimes the currentlengthof thehashtable.If the
keywas already in theHashMap, return the old value saved in Step 2. Otherwise, returnnull
Testing the put Method
Before moving on to the next part of the lab, we should create unit tests to verify our implementation so far and help us find and remove any bugs. As in previous labs, we can create a Java file that will contain our unit tests by right clicking anywhere in the MyHashMap.java file and selecting “Source Action” from the right click menu. Then, select “Generate Tests”. Use the default name proposed by the IDE of MyHashMapTest. Next, it will prompt you with what methods you want to create tests for.
Inside the newly created MyHashMapTest.java file, create a unit test verifying that the put method works properly. As one strategy, you could:
- Create a new
MyHashMap<String, Integer>instance - Save a number
valuefor a new Stringkeyand make sure that theputmethod returnsnullsince thekeywas new - Save a new number
valuefor an existing Stringkeyand make sure that theputmethod returns the previous value stored for thatkey
You can also now create unit tests for your get method described in Part 2 of the lab, as well as the size, isEmpty, and clear methods described in Part 1 of the lab.
Hint
Remember the Debugger in Visual Studio Code, which will allow you to inspect the values of variables as you debug your unit tests.
You might also want to temporarily make your find, insert, and resize methods public so that you can call them within your unit tests (since they do the majority of the work of the get and put methods).
Committing Your Progress
Don’t forget to frequently save your progress to GitHub using the add/commit/push commands with git.