package class9_1_HashMap; import java.util.*; /** * Note: This class has problems, as discussed in class. * * @param key contained. * @param value associated with key */ public class ChainingHashMap implements Map { private int MAX_SIZE = 3; // 1024 == 2^10 ~= 10^3 KB KiB = 1024 bytes private List[] table; private int size; private class Entry { private K key; private V value; private Entry(K key, V value) { this.key = key; this.value = value; } @Override // TODO: Ought to implement hashCode, too // though I think the class will work without it. public boolean equals(Object obj) { return key.equals(((Entry)obj).key); } } public ChainingHashMap() { table = (List[]) new List[MAX_SIZE]; size = 0; } /** * Returns true if this map contains a mapping for the specified * key. More formally, returns true if and only if * this map contains a mapping for a key k such that * (key==null ? k==null : key.equals(k)). (There can be * at most one such mapping.) * * @param key key whose presence in this map is to be tested * @return true if this map contains a mapping for the specified * key * @throws ClassCastException if the key is of an inappropriate type for * this map * (optional) * @throws NullPointerException if the specified key is null and this map * does not permit null keys * (optional) */ @Override public boolean containsKey(Object key) { throw new UnsupportedOperationException("TODO: Homework"); } /** * 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 by the specified value. * * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with key, or * null if there was no mapping for key. * (A null return can also indicate that the map * previously associated null with key, * if the implementation supports null values.) * @throws NullPointerException if the specified key or value is null * and this map does not permit null keys or values */ @Override public V put(K key, V value) { if(key == null) { throw new NullPointerException("Key is null. (Null keys not accepted in this implementation.)"); } boolean isChanged = false; int hash = key.hashCode(); hash = Math.abs(hash) % MAX_SIZE; V oldValue; if(table[hash] == null) { table[hash] = new LinkedList(); table[hash].add(new Entry(key, value)); oldValue = null; size++; } else { if(table[hash].contains(key)) { System.out.println("DEBUG: Key found; replacing. Key:"+key); int oldIndex = table[hash].indexOf(new Entry(key,null)); oldValue = table[hash].remove(oldIndex).value; } else { System.out.println("DEBUG: Key not found. Adding: "+ key); table[hash].add(new Entry(key, value)); oldValue = null; size++; } } return oldValue; } @Override public void clear() { for(int i=0; itrue if this map maps one or more keys to the * specified value. More formally, returns true if and only if * this map contains at least one mapping to a value v such that * (value==null ? v==null : value.equals(v)). This operation * will probably require time linear in the map size for most * implementations of the Map interface. * * @param value value whose presence in this map is to be tested * @return true if this map maps one or more keys to the * specified value * @throws ClassCastException if the value is of an inappropriate type for * this map * (optional) * @throws NullPointerException if the specified value is null and this * map does not permit null values * (optional) */ @Override public boolean containsValue(Object value) { return false; } /** * Returns the value to which the specified key is mapped, * or {@code null} if this map contains no mapping for the key. *

*

More formally, if this map contains a mapping from a key * {@code k} to a value {@code v} such that {@code (key==null ? k==null : * key.equals(k))}, then this method returns {@code v}; otherwise * it returns {@code null}. (There can be at most one such mapping.) *

*

If this map permits null values, then a return value of * {@code null} does not necessarily indicate that the map * contains no mapping for the key; it's also possible that the map * explicitly maps the key to {@code null}. The {@link #containsKey * containsKey} operation may be used to distinguish these two cases. * * @param key the key whose associated value is to be returned * @return the value to which the specified key is mapped, or * {@code null} if this map contains no mapping for the key * @throws ClassCastException if the key is of an inappropriate type for * this map * (optional) * @throws NullPointerException if the specified key is null and this map * does not permit null keys * (optional) */ @Override public V get(Object key) { return null; } /** * Copies all of the mappings from the specified map to this map * (optional operation). The effect of this call is equivalent to that * of calling {@link #put(Object, Object) put(k, v)} on this map once * for each mapping from key k to value v in the * specified map. The behavior of this operation is undefined if the * specified map is modified while the operation is in progress. * * @param m mappings to be stored in this map * @throws UnsupportedOperationException if the putAll operation * is not supported by this map * @throws ClassCastException if the class of a key or value in the * specified map prevents it from being stored in this map * @throws NullPointerException if the specified map is null, or if * this map does not permit null keys or values, and the * specified map contains null keys or values * @throws IllegalArgumentException if some property of a key or value in * the specified map prevents it from being stored in this map */ @Override public void putAll(Map m) { } /** * Returns a {@link Set} view of the keys contained in this map. * The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through * the iterator's own remove operation), the results of * the iteration are undefined. The set supports element removal, * which removes the corresponding mapping from the map, via the * Iterator.remove, Set.remove, * removeAll, retainAll, and clear * operations. It does not support the add or addAll * operations. * * @return a set view of the keys contained in this map */ @Override public Set keySet() { return null; } /** * Returns a {@link Collection} view of the values contained in this map. * The collection is backed by the map, so changes to the map are * reflected in the collection, and vice-versa. If the map is * modified while an iteration over the collection is in progress * (except through the iterator's own remove operation), * the results of the iteration are undefined. The collection * supports element removal, which removes the corresponding * mapping from the map, via the Iterator.remove, * Collection.remove, removeAll, * retainAll and clear operations. It does not * support the add or addAll operations. * * @return a collection view of the values contained in this map */ @Override public Collection values() { return null; } /** * Returns a {@link Set} view of the mappings contained in this map. * The set is backed by the map, so changes to the map are * reflected in the set, and vice-versa. If the map is modified * while an iteration over the set is in progress (except through * the iterator's own remove operation, or through the * setValue operation on a map entry returned by the * iterator) the results of the iteration are undefined. The set * supports element removal, which removes the corresponding * mapping from the map, via the Iterator.remove, * Set.remove, removeAll, retainAll and * clear operations. It does not support the * add or addAll operations. * * @return a set view of the mappings contained in this map */ @Override public Set> entrySet() { return null; } }