Hashing

advertisement
CS60
Data Structures
HW-3
Homework #3
Hashing
For this project we will be writing two hashing schemes (chaining and linear probing). You will
need to write four classes: AbstractHashMap (super-class of the next two classes), ChainHashMap (implements linked list chain), LinearHashMap (implements linear probing on a
single array), and TestHashMap (to text the whole thing).
AbstractHashMap
This abstract class will define:

The protected symbolic constant (DEFAULT_BUCKETS) which is the number of
buckets in the hash array if a default constructor is called (use 17 as the default value).

The protected inner class (Entry) which will represent the data entry for the map.
This class will contain the protected data members key and value. It will also contain the overridden methods equals() and toString(). The equals() method
will only compare the key data member, the value data member will be ignored for
this method. The format of the string returned by toString() will be:
“<key(hashIndex) => value>” (see below regarding the hashIndex).

The protected array (map) which holds the hashed entries. Since the chaining implementation will contain List entries and the linear implementation will contain Entry entries we will declare the array to be of type Object so that either type of objects
will fit into the array.

The protected integer number of buckets (nBuckets) to be allocated to the hash array. This value will be set by the constructor to be either the default value (defined
above) or the parameter of the constructor.

The protected integer number of elements currently stored in the hash map size).

The protected method int getIndex(Object key) which calls the hashCode() method on the object key and then returns the value of the hash modulo the
number of buckets in the hash array.

The protected abstract method Entry getEntry(Object key) which
will be defined by the derived classes. This method will return either the Entry object
containing the key or the value null if the key is not found. The derived classes will
implement this method as appropriate to their implementation.

The protected abstract method void newEntry(Object key, Object
value) which will be defined by the derived classes. This method will add a new entry
to the map. We should assume that prior to calling this method the client code has called
getEntry() and verified that the entry does not exist in the map. The derived classes
will implement this method as appropriate to their implementation.
Page 1 of 3
CS60
Data Structures
HW-3

The public method int size() which returns the current number of elements in the
map.

The public method Object get(Object key) which calls getEntry() and
returns the value of the Entry with the specified Key. This method is inherited by the
derived classes and calls getEntry() polymorphicly.

The public method Object put(Object key, Object newValue) which
calls getEntry() to see if the entry already exists. If it does then the old value will
be returned and the newValue will be set. If the entry does not already exist then it will
call newEntry() to create the new entry and store it in the proper place. This method
is inherited by the derived classes and calls getEntry() and newEntry() polymorphicly.

The public method void display() which prints the size of the map and the contents of the elements of the map to System.out. Note: since Entry has a
toString() method and List has a toString() method (a comma separated list
of items inside square brackets ([…])), the hash map array elements can just be sent to
the println() method which will handle the proper formatting. Note also: if any element is null then the println() method will display the string “null” which is
what we want. See sample output report for proper formatting of data.
ChainHashMap
This concrete class extends the abstract class and will define:

The default constructor.

The constructor which takes an integer argument (number of buckets).

The protected method Entry getEntry(Object key) which will return either
the Entry object containing the key or the value null if the key is not found.

The protected method void newEntry(Object key, Object value)
which will add a new entry to the map. We should assume that prior to calling this method the client code has called getEntry() and verified that the entry does not exist in
the map.

All other methods are inherited from the abstract super-class.
LinearHashMap
This concrete class extends the abstract class and will define:

The default constructor.

The constructor which takes an integer argument (number of buckets).

The protected method Entry getEntry(Object key) which will return either
the Entry object containing the key or the value null if the key is not found.
Page 2 of 3
CS60
Data Structures
HW-3

The protected method void newEntry(Object key, Object value)
which will add a new entry to the map. We should assume that prior to calling this method the client code has called getEntry() and verified that the entry does not exist in
the map.

All other methods are inherited from the abstract super-class.
TestHashMap
This class is given here:
import java.util.Random;
public class TestHashMap {
public static final int RANGE = 100;
public static final int NUM_ITEMS = 25;
public static void main(String[] args) {
ChainHashMap mc = new ChainHashMap();
LinearHashMap ml = new LinearHashMap(NUM_ITEMS * 2 + 3);
Random rand = new Random();
Object key, value, oldValue;
for (int i = 0; i < NUM_ITEMS; i++) {
key = new Integer(rand.nextInt(RANGE));
value = Integer.toString(i);
oldValue = mc.put(key, value);
if (oldValue != null)
System.out.println("Duplicate entry for key: " + key +
", was: " + oldValue + ", now: " + value);
oldValue = ml.put(key, value);
}
mc.display();
System.out.println();
ml.display();
}
}
If you are interested in playing around with Java 5 generics, you can modify the above to generify the classes and make them more universal.
Have fun!
Page 3 of 3
Download