Gettysburg College

CS 216
Data Structures

Spring 2024

Assignment 4

Due: Mon, Feb 19, by 11:59pm
  • method stubs: CHashMap.java, LHashMap.java, Entry.java
  • working constructors and toString
  • coverage.pdf
  • api.pdf only for CHashMap
  • junit tests: CHashMapTest.java and LHashMap.java
    • testers confirm that constructors and toString work
    • use class MyString (see section Testing at bottom)
    • make sure to read the whole Section Testing at the bottom before writing the JUnit tests
Due: Thu, Feb 22, by 11:59pm
  • CHashMap.java, LHashMap.java, Entry.java
  • CHashMapTest.java and LHashMapTest.java
  • coverage-CHashMap.pdf and coverage-LHashMap.pdf

Description

In this assignment you will implement the HashMap data structure. The HashMap can be viewed as a generalization of the primitive array or ArrayList. We still use indices to store data in the HashMap, but here the indices do not need to be sequential, and in fact, the indices do not need to be integers.

For a detailed example see here:

Hash Map Example

Quick summary:

Inserting in a HashMap
Calculate the bucket index i where the item would have been inserted: Searching in a HashMap
Calculate the bucket index i where the item would have been inserted: Deleting from a HashMap
Calculate the bucket index i where the item would have been inserted:

Testing

See Section "Testing" at the very bottom.

Implementation

Create two separate projects called CHashMap and LHashMap that implement the methods given below using the Chaining and Linear Probing collision resolution schemes:

Keep in mind that you will need to:

The Entry Class

This is a with only two data members (key and value). This class is loosely an analog of Node for LinkedList.

For this assignment Entry will be an external class, i.e. in its own file. It is a generic class on two types <K, V> (for comparison, the LinkedList was generic on only one type <E>). Since the class is external you need to write Entry<K, V>, i.e. explicitly mention the generic type K and V, unlike Node which was internal, so the generic type E was implicit and was not written.

The Entry class has method toString that returns the contents in this format

cat:4

assuming the entry has key "cat" and value "4" (just plus the two things with the ":")

The Map Methods

Setup

Use a primitive array for the buckets:

data member sectionconstructor
LHashMap
Entry<K, V>[] _array-name_;
_array-name_ = (Entry<K, V>[]) new Entry[ ... ];
CHashMap
LinkedList<Entry<K, V>>[] _array-name_;
_array-name_ = (LinkedList<Entry<K, V>>[]) new LinkedList[ ... ];
  • Each map needs to have a data member to keep track of the size (i.e. number of entries)

  • LHashMap only: needs to have two Entry data members to represent the Empty and Deleted buckets; this is similar to the dummy node in the LinkedList, but now the "dummys" are data members

  • must use enhanced for-loop wherever possible

?HashMap(int initialCapacity, double loadFactor)

Creates a map with the given capacity and load factor; make sure to put empty buckets in the hash map container (empty lists for Chaining, Empty marker for Linear Probing).

The loadFactor is a number in [0..1]. Initially, just assign it and ignore it.

boolean isEmpty()

Determines if the map is empty; this method must run in time O(1), i.e. no loops.
int size()

Returns the number of (key, value) pairs stored in this map. This method must run in time O(1), i.e. no loops. The methods put and remove should keep track of the current size.
V put(K key, V value)

Puts the given value under the given key and returns the old value associated with this key (or null if the key was not in the map).
V get(K key)

Returns the value associated with the given key (or null if the key was not in the map).
V remove(K key)

Removes/deletes the entry with the given key from the map and returns the value associated with this key (or null if the key was not in the map).
void clear()

clears the map
boolean containsKey(K key)

Determines if the map contains an element with the given key/index.
boolean containsValue(V value)

Determines if the map contains the given value.

For LHashMap implement this using the iterator over the values in the map. This method will indirectly test the iterator.

void rehash()

(private) Expands the map storage (after adding *new* entry) if size ≥ load_factor * capacity. Rehashes all the key/value pairs (use the method put; do not simply copy entries).

After rehashing, the map capacity has doubled (twice as many buckets) and the contents is arranged as if someone collected all entries in left-to-right, top-to-bottom order and put them in an initially empty map.

This method is called only when a brand new package is entered in the map.

String toString()

Returns a string representation of the map. Here are examples of maps with capacity 10 -- one map has 4 entries and the other map is empty, i.e. has no entries:
  • for LHashMap returns (letter E is written for Empty marker, letter D for Deleted marker)

    4:[D E 76544632:mickey 14742300:donald D 67587658:minnie E E D 22571632:tom]
    0:[E E E E E E] (for empty map)

  • for CHashMap returns:

    4:[[] [] [] [] [76544632:mickey 14742300:donald 67587658:minnie] [] [] [22571632:tom] [] []]
    0:[[] [] [] [] [] [] [] [] [] []] (for empty map)

  • the first number is the size of the map, i.e. number of entries, not number of buckets

  • in CHashMapTest and LHashMapTest, respectively, create an empty map of 10 buckets (default) and assert that you got the correct string

  • no if statements and only one loop is needed in each case, since LinkedList and Entry have method toString, so you can simply write:

    LHashMap:      str = str + entry

    CHashMap:      str = str + list_of_entries

    in CHashMap there will be commas, so to remove at the end write:

    str = str.replaceAll(",", "")

Iterator<V> iterator()

Returns an iterator over the values stored in this map (in no particular order); operation remove is not implemented.

You are only expected to implement iterator for LHashMap class. This will be similar to the Stack iterator, but hasNext() will have a loop.

No test cases required. Tested implicitly.

Testing

For testing:


What to turn in

Create projects CHashMap and LHashMap with files

Turn in: