/** * CSE 373, Winter 2011, Jessica Miller * This is a generic hash table implementation of the Set ADT. * In order to make this class generic like Java's HashSet, we have: * 1. replaced all references to Strings with the placeholder T * 2. allowed nulls to be inserted into the Set without crashing * 3. changed the private hash method from being a hashing function * for Strings, to using the element's hashCode method */ public class HashSet implements Set { private static final int DEFAULT_SIZE = 11; private HashSetEntry[] table; private int size; public HashSet() { this(DEFAULT_SIZE); } @SuppressWarnings("unchecked") public HashSet(int tableSize) { table = new HashSetEntry[tableSize]; size = 0; } /** * Adds the specified String to the Set if it is not already present. * @return true if this set did not already contain the String */ public boolean add(T value) { // figure out where value should be... int valuePosition = hash(value); // check to see if the value is in the set HashSetEntry temp = table[valuePosition]; while (temp != null) { if ((temp.data == null && value == null) || (temp.data != null && temp.data.equals(value))) { return false; } temp = temp.next; } table[valuePosition] = new HashSetEntry(value, table[valuePosition]); size++; // otherwise, the value was not found and was inserted return true; } /** * Returns true if the set contains the specified String. */ public boolean contains(T value) { // figure out where value should be... int valuePosition = hash(value); // check to see if the value is in the set HashSetEntry temp = table[valuePosition]; while (temp != null) { if ((temp.data == null && value == null) || (temp.data.equals(value))) { return true; } temp = temp.next; } // otherwise, the value was not found return false; } /** * Prints the set in a hash table-like format. */ public void print() { for (int i = 0; i < table.length; i++) { System.out.printf("%d: ", i); HashSetEntry temp = table[i]; while (temp != null) { System.out.print(temp.data); if (temp.next != null) { System.out.print(" --> "); } temp = temp.next; } System.out.println(); } } /** * Removes the specified String from this set if it is present. * @return true if this set contained the specified element */ public boolean remove(T value) { int valuePosition = hash(value); // empty bucket if (table[valuePosition] == null) { return false; } // removing front if ((table[valuePosition].data == null && value == null) || (table[valuePosition].data != null && table[valuePosition].data.equals(value))) { table[valuePosition] = table[valuePosition].next; size--; return true; } // find value to remove HashSetEntry temp = table[valuePosition]; while (temp.next != null) { if ((temp.next.data == null && value == null) || (temp.next.data != null && temp.next.data.equals(value))) { temp.next = temp.next.next; size--; return true; } temp = temp.next; } return false; } /** * Returns the number of elements in this set (its cardinality) */ public int size() { return size; } private int hash(T data) { if (data == null) { return 0; } else { return Math.abs(data.hashCode() % table.length); } } }