import java.util.Set; /** * Your implementation hashmap.MyHashMap should implement this interface. To do so, * append "implements hashmap.Map61B<K, V>" to the end of your "public class..." * declaration, though you can use other formal type parameters if you'd like. */ publicinterfaceMap61B<K, V> extendsIterable<K> { /** Removes all of the mappings from this map. */ voidclear();
/** Returns true if this map contains a mapping for the specified key. */ booleancontainsKey(K key);
/** * Returns the value to which the specified key is mapped, or null if this * map contains no mapping for the key. */ V get(K key);
/** Returns the number of key-value mappings in this map. */ intsize();
/** * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for the key, * the old value is replaced. */ voidput(K key, V value);
/** Returns a Set view of the keys contained in this map. */ Set<K> keySet();
/** * Removes the mapping for the specified key from this map if present. * Not required for Lab 8. If you don't implement this, throw an * UnsupportedOperationException. */ V remove(K key);
/** * Removes the entry for the specified key only if it is currently mapped to * the specified value. Not required for Lab 8. If you don't implement this, * throw an UnsupportedOperationException. */ V remove(K key, V value); }
/** * A hash table-backed Map implementation. Provides amortized constant time * access to elements via get(), remove(), and put() in the best case. * * Assumes null keys will never be inserted, and does not resize down upon remove(). * @author YOUR NAME HERE */ publicclassMyHashMap<K, V> implementsMap61B<K, V> {
protectedclassNode { K key; V value;
Node(K k, V v) { key = k; value = v; } }
/* Instance Variables */ private Collection<Node>[] buckets; // You should probably define some more!
/** * MyHashMap constructor that creates a backing array of initialSize. * The load factor (# items / # buckets) should always be <= loadFactor * * @param initialSize initial size of backing array * @param maxLoad maximum load factor */ publicMyHashMap(int initialSize, double maxLoad) { capacity = initialSize; buckets = createTable(capacity); loadFactor = maxLoad; size = 0; }
/** * Returns a new node to be placed in a hash table bucket */ private Node createNode(K key, V value) { returnnewNode(key, value); }
/** * Returns a data structure to be a hash table bucket * * The only requirements of a hash table bucket are that we can: * 1. Insert items (`add` method) * 2. Remove items (`remove` method) * 3. Iterate through items (`iterator` method) * * Each of these methods is supported by java.util.Collection, * Most data structures in Java inherit from Collection, so we * can use almost any data structure as our buckets. * * Override this method to use different data structures as * the underlying bucket type * * BE SURE TO CALL THIS FACTORY METHOD INSTEAD OF CREATING YOUR * OWN BUCKET DATA STRUCTURES WITH THE NEW OPERATOR! */ protected Collection<Node> createBucket() { returnnewArrayList<>(); }
/** * Returns a table to back our hash table. As per the comment * above, this table can be an array of Collection objects * * BE SURE TO CALL THIS FACTORY METHOD WHEN CREATING A TABLE SO * THAT ALL BUCKET TYPES ARE OF JAVA.UTIL.COLLECTION * * @param tableSize the size of the table to create */ private Collection<Node>[] createTable(int tableSize) { return (Collection<Node>[]) newCollection[tableSize]; }
// TODO: Implement the methods of the Map61B Interface below // Your code won't compile until you do so!
/** * Removes all of the mappings from this map. */ @Override publicvoidclear() { MyHashMap<K, V> newTable = newMyHashMap<>(); size = newTable.size(); capacity = newTable.capacity; loadFactor = newTable.loadFactor; buckets = newTable.buckets; }
/** * Returns true if this map contains a mapping for the specified key. * * @param key */ @Override publicbooleancontainsKey(K key) { if (key == null) { thrownewIllegalArgumentException("key is null in containsKey() function"); } return get(key) != null; }
/** * Returns the value to which the specified key is mapped, or null if this * map contains no mapping for the key. * * @param key */ @Override public V get(K key) { if (key == null) { thrownewIllegalArgumentException("the key is null in get() function"); } Collection<Node> bucket = getBucket(key); if (bucket != null) { for (Node node : bucket) { if (node.key.equals(key)) { return node.value; } } } returnnull; }
/** * Returns the number of key-value mappings in this map. */ privateinthashCode(K num) { return Math.abs(num.hashCode()) % capacity; } private Collection<Node> getBucket(K k) { intindex= hashCode(k); return buckets[index]; } @Override publicintsize() { return size; }
/** * Associates the specified value with the specified key in this map. * If the map previously contained a mapping for the key, * the old value is replaced. * * @param key * @param value */ @Override publicvoidput(K key, V value) { Collection<Node> bucket = getBucket(key); if (bucket == null) { // if bucket dont exist intindex= hashCode(key); buckets[index] = createBucket(); bucket = buckets[index]; } putIn(bucket, key, value); doubleload= (double) size() /capacity; if (load > loadFactor) { resize(2 * capacity); } }
privatevoidputIn(Collection<Node> bucket, K key, V value) { for (Node x : bucket) { // iterate the bucket if (x.key.equals(key)) { // find the exact key x.value = value; return; } } bucket.add(newNode(key, value)); size++; } /** * Returns a Set view of the keys contained in this map. */ @Override public Set<K> keySet() { Set<K> keySet = newHashSet<>(); for (Collection<Node> bucket : buckets) { if (bucket != null) { for (Node node : bucket) { keySet.add(node.key); } } } return keySet; }
/** * Removes the mapping for the specified key from this map if present. * Not required for Lab 8. If you don't implement this, throw an * UnsupportedOperationException. * * @param key */ @Override public V remove(K key) { thrownewUnsupportedOperationException(); }
/** * Removes the entry for the specified key only if it is currently mapped to * the specified value. Not required for Lab 8. If you don't implement this, * throw an UnsupportedOperationException. * * @param key * @param value */ @Override public V remove(K key, V value) { thrownewUnsupportedOperationException(); }
/** * Returns an iterator over elements of type {@code T}. * * @return an Iterator. */ @Override public Iterator<K> iterator() { returnnull; }
/** * Protected helper class to store key/value pairs * The protected qualifier allows subclass access */