// Textbook fragment 09.05 /** Put a key-value pair in the map, replacing previous one if it exists. */ public V put (K key, V value) throws InvalidKeyException { int i = findEntry(key); //find the appropriate spot for this entry if (i >= 0) // this key has a previous value return ((HashEntry) bucket[i]).setValue(value); // set new value if (n >= capacity/2) { rehash(); // rehash to keep the load factor <= 0.5 i = findEntry(key); //find again the appropriate spot for this entry } bucket[-i-1] = new HashEntry(key, value); // convert to proper index n++; return null; // there was no previous value } /** Doubles the size of the hash table and rehashes all the entries. */ protected void rehash() { capacity = 2*capacity; Entry[] old = bucket; bucket = (Entry[]) new Entry[capacity]; // new bucket is twice as big java.util.Random rand = new java.util.Random(); scale = rand.nextInt(capacity-1) + 1; // new hash scaling factor shift = rand.nextInt(capacity); // new hash shifting factor for (int i=0; i e = old[i]; if ((e != null) && (e != AVAILABLE)) { // a valid entry int j = - 1 - findEntry(e.getKey()); bucket[j] = e; } } } /** Removes the key-value pair with a specified key. */ public V remove (K key) throws InvalidKeyException { int i = findEntry(key); // find this key first if (i < 0) return null; // nothing to remove V toReturn = bucket[i].getValue(); bucket[i] = AVAILABLE; // mark this slot as deactivated n--; return toReturn; } }