set(key, value) {

        // first, ensure the key is valid
        assertNonEmptyString(key);

        /*
         * Next, calculate the hash code from the string key. The hash code
         * is then used to determine the index into the array where the data
         * should be stored.
         */
        const hashCode = hashCodePoints(key);
        const index = getArrayIndexFromHashCode(hashCode);

        /*
         * Special case: If the calculated index in the array hasn't yet
         * been initialized, then create a new linked list in that
         * location before continuing.
         * 
         * Note: It's not necessary to use a linked list. Because JavaScript
         * has an excellent `Array` class, you could also just use an array
         * here. This implementation sticks with a linked list because that's
         * the most common implementation in other languages.
         */
        if (this[array][index] === undefined) {
            this[array][index] = new DoublyLinkedList();
        }

        /*
         * Check to see if the exact key is already present
         * in the hash map. If so, then just update the value.
         */
        const result = this[array][index].find((value) => {
            return value.key === key;
        });

        // If the key doesn't already exist, then add it
        if (result === undefined) {
            
            /*
             * Add everything we know about this key-value pair, including the key,
             * the value, and the hash code. We will need all of these later.
             */
            this[array][index].add({
                key,
                value
            });
        } else {

            // The key already exists in the hash map, so just update the value.
            result.value = value;
        }

    }
Adds a key-value pair into the hash map.
@param {string} key The key to add.
@param {*} value The value to add.
@returns {void}
@throws {TypeError} If the key isn't a non-empty string.