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
key
for theentry
using itsgetKey()
method and calculates the appropriateindex
as in Step 1 of thefind
method from Part 2 of the lab.Gets the appropriate
LinkedList
from thehashtable
using theindex
calculated in Step 1.Adds the given
entry
to theLinkedList
found 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 key
s collide by having the same index
into the hashtable
’s bucket array based on their (different) hashCode
s. 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
hashtable
as a different variableCreate a new array for the
hashtable
instance variable using the providedcreateTable
method, passing in double thelength
of the oldhashtable
so 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 everyLinkedList
in the oldhashtable
and callput
to re-hash and re-insert thekey/value
pairs.
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
find
method developed above to look up whetherkey
was already in theMyHashMap
If
find
returns aSimpleEntry<K, V>
object becausekey
was already in theHashMap
, save the previous value from theSimpleEntry<K, V>
and change the value to thevalue
passed into the method usingSimpleEntry
’ssetValue(value)
methodIf
find
instead returnednull
becausekey
was not already in theHashMap
, then we need to create a newSimpleEntry<K, V>
storing the givenkey
andvalue
that were arguments to theput
method. Call theinsert
helper method described above, and increase thesize
of theMyHashMap
since a newkey
was inserted.Next, check whether we need to resize the
hashtable
so that we can minimize the risk of collisions. This should occur whenever thesize
of theMyHashMap
is greater thanLOAD_FACTOR
times the currentlength
of thehashtable
.If the
key
was 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
value
for a new Stringkey
and make sure that theput
method returnsnull
since thekey
was new - Save a new number
value
for an existing Stringkey
and make sure that theput
method 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.