package rebelsky.exam4; import java.util.Vector; /** * A simple implementation of linear-probe hash tables. In this * implementation, the client must specify the size in advance and * the table is always that size. Hence, we hope that the client * will never put more than half that many elements in the hash table. * * @author Samuel A. Rebelsky * @version 1.0 of November 2005 */ public class LinearProbeHashTable { // +--------+-------------------------------------------------- // | Fields | // +--------+ /** * The underlying vector that stores all the values. */ Vector> contents; /** * The capacity of the hash table. */ int capacity; /** * The number of elements actually in the hash table. */ int size; // +--------------+-------------------------------------------- // | Constructors | // +--------------+ /** * Create a hash table with capacity cap. Note that when the * hash table is near capacity, it will not behave efficiently. */ public LinearProbeHashTable(int cap) { this.contents = new Vector>(cap); this.contents.setSize(cap); this.size = 0; this.capacity = cap; } // LinearProbeHashTable(int cap) // +----------------+------------------------------------------ // | Public Methods | // +----------------+ public void put(K key, V value) throws Exception { // Determine the expected position of the key/value pair. int pos = this.find(key); // Put a new key/value pair there. this.contents.set(pos, new KeyedValue(key,value)); } // put(K,V) public V get(K key) throws Exception { // Determine the expected position of the key/value pair. int pos = this.find(key); // Get the pair that's there KeyedValue stuff = this.contents.get(pos); // If nothing was there, fail if (stuff == null) { throw new Exception("Failed to find a value with key " + key.toString()); } // Otherwise, we're okay, use the value. return stuff.value; } // get() public boolean isEmpty() { return (this.size == 0); } // isEmpty() public boolean isFull() { return (this.size == this.capacity); } // isFull() public int size() { return this.size; } // size() public void remove(K key) { // STUB } public String toString() { return this.contents.toString(); } // toString() // +----------------+------------------------------------------ // | Helper Methods | // +----------------+ /** * Determine the position in which something with key falls * or the first empty space afterwards, if the key does not * appear. Throws an exception if it finds neither key nor space. */ int find(K key) throws Exception { int start = Math.abs(key.hashCode()) % this.capacity; // Try every position, which we determine by offsetting // from the starting position. for (int offset = 0; offset < this.capacity; offset++) { int pos = (start + offset) % this.capacity; // If there's nothing there, return the position. if (this.contents.get(pos) == null) { return pos; } // If the matching thing is there, return the position. else if (key.equals(this.contents.get(pos).key)) { return pos; } } // for // At this point, we've tried every space, so give up. throw new Exception("Failed to find space for " + key.toString()); } // find(K) } // class LinearProbeHashTable