package java.util;

import ej.annotation.Nullable;

/**
 * This class implements a hash table, which maps keys to values. Any non-<code>null</code> object
 * can be used as a key or as a value.
 * <p>
 *
 * To successfully store and retrieve objects from a hashtable, the objects used as keys must
 * implement the <code>hashCode</code> method and the <code>equals</code> method.
 * <p>
 *
 * An instance of <code>Hashtable</code> has two parameters that affect its performance: <i>initial
 * capacity</i> and <i>load factor</i>. The <i>capacity</i> is the number of <i>buckets</i> in the
 * hash table, and the <i>initial capacity</i> is simply the capacity at the time the hash table is
 * created. Note that the hash table is <i>open</i>: in the case of a "hash collision", a single
 * bucket stores multiple entries, which must be searched sequentially. The <i>load factor</i> is a
 * measure of how full the hash table is allowed to get before its capacity is automatically
 * increased. The initial capacity and load factor parameters are merely hints to the
 * implementation. The exact details as to when and whether the rehash method is invoked are
 * implementation-dependent.
 * <p>
 *
 * Generally, the default load factor (.75) offers a good tradeoff between time and space costs.
 * Higher values decrease the space overhead but increase the time cost to look up an entry (which
 * is reflected in most <code>Hashtable</code> operations, including <code>get</code> and <code>put</code>).
 * <p>
 *
 * The initial capacity controls a tradeoff between wasted space and the need for
 * <code>rehash</code> operations, which are time-consuming. No <code>rehash</code> operations will
 * <i>ever</i> occur if the initial capacity is greater than the maximum number of entries the
 * <code>Hashtable</code> will contain divided by its load factor. However, setting the initial capacity
 * too high can waste space.
 * <p>
 *
 * If many entries are to be made into a <code>Hashtable</code>, creating it with a sufficiently
 * large capacity may allow the entries to be inserted more efficiently than letting it perform
 * automatic rehashing as needed to grow the table.
 * <p>
 *
 * This example creates a hashtable of numbers. It uses the names of the numbers as keys:
 *
 * <pre>
 * {
 * 	&#064;code
 * 	Hashtable&lt;String, Integer&gt; numbers = new Hashtable&lt;String, Integer&gt;();
 * 	numbers.put(&quot;one&quot;, 1);
 * 	numbers.put(&quot;two&quot;, 2);
 * 	numbers.put(&quot;three&quot;, 3);
 * }
 * </pre>
 *
 * <p>
 * To retrieve a number, use the following code:
 *
 * <pre>
 * {
 * 	&#064;code
 * 	Integer n = numbers.get(&quot;two&quot;);
 * 	if (n != null) {
 * 		System.out.println(&quot;two = &quot; + n);
 * 	}
 * }
 * </pre>
 *
 * <p>
 * The iterators returned by the <code>iterator</code> method of the collections returned by all of this
 * class's "collection view methods" are <em>fail-fast</em>: if the Hashtable is structurally
 * modified at any time after the iterator is created, in any way except through the iterator's own
 * <code>remove</code> method, the iterator will throw a {@link ConcurrentModificationException}. Thus,
 * in the face of concurrent modification, the iterator fails quickly and cleanly, rather than
 * risking arbitrary, non-deterministic behavior at an undetermined time in the future. The
 * Enumerations returned by Hashtable's keys and elements methods are <em>not</em> fail-fast.
 *
 * <p>
 * Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally
 * speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent
 * modification. Fail-fast iterators throw <code>ConcurrentModificationException</code> on a best-effort
 * basis. Therefore, it would be wrong to write a program that depended on this exception for its
 * correctness: <i>the fail-fast behavior of iterators should be used only to detect bugs.</i>
 *
 * @param <K>
 *        the type of the keys maintained by this map
 * @param <V>
 *        the type of the mapped values
 *
 * @see Object#equals(java.lang.Object)
 * @see Object#hashCode()
 * @see Hashtable#rehash()
 * @see Collection
 * @see Map
 * @see HashMap
 */
public class Hashtable<K, V> extends Dictionary<K, V> implements Map<K, V>, Cloneable, java.io.Serializable {

    /**
     * Constructs a new, empty hashtable with a default initial capacity (11) and load factor (0.75).
     */
    public Hashtable() {
        throw new RuntimeException();
    }

    /**
     * Constructs a new, empty hashtable with the specified initial capacity and default load factor
     * (0.75).
     *
     * @param initialCapacity
     *        the initial capacity of the hashtable.
     * @exception IllegalArgumentException
     *            if the initial capacity is less than zero.
     */
    public Hashtable(int initialCapacity) {
        throw new RuntimeException();
    }

    /**
     * Constructs a new, empty hashtable with the specified initial capacity and the specified load
     * factor.
     *
     * @param initialCapacity
     *        the initial capacity of the hashtable.
     * @param loadFactor
     *        the load factor of the hashtable.
     * @exception IllegalArgumentException
     *            if the initial capacity is less than zero, or if the load factor is nonpositive.
     */
    public Hashtable(int initialCapacity, float loadFactor) {
        throw new RuntimeException();
    }

    /**
     * Constructs a new hashtable with the same mappings as the given Map. The hashtable is created with
     * an initial capacity sufficient to hold the mappings in the given Map and a default load factor
     * (0.75).
     *
     * @param t
     *        the map whose mappings are to be placed in this map.
     * @throws NullPointerException
     *         if the specified map is null.
     */
    public Hashtable(Map<? extends K, ? extends V> t) {
        throw new RuntimeException();
    }

    /**
     * Clears this hashtable so that it contains no keys.
     */
    @Override
    public void clear() {
        throw new RuntimeException();
    }

    /**
     * Creates a shallow copy of this hashtable. All the structure of the hashtable itself is copied,
     * but the keys and values are not cloned. This is a relatively expensive operation.
     *
     * @return a clone of the hashtable
     */
    @Override
    public Object clone() {
        throw new RuntimeException();
    }

    /**
     * Tests if some key maps into the specified value in this hashtable. This operation is more
     * expensive than the {@link #containsKey containsKey} method.
     *
     * <p>
     * Note that this method is identical in functionality to {@link #containsValue containsValue},
     * (which is part of the {@link Map} interface in the collections framework).
     *
     * @param value
     *        a value to search for
     * @return <code>true</code> if and only if some key maps to the <code>value</code> argument in this
     *         hashtable as determined by the <code>equals</code> method; <code>false</code> otherwise.
     * @exception NullPointerException
     *            if the value is <code>null</code>
     */
    public boolean contains(Object value) {
        throw new RuntimeException();
    }

    /**
     * Tests if the specified object is a key in this hashtable.
     *
     * @param key
     *        possible key
     * @return <code>true</code> if and only if the specified object is a key in this hashtable, as
     *         determined by the <code>equals</code> method; <code>false</code> otherwise.
     * @throws NullPointerException
     *         if the key is <code>null</code>
     * @see #contains(Object)
     */
    @Override
    public boolean containsKey(Object key) {
        throw new RuntimeException();
    }

    /**
     * Returns true if this hashtable maps one or more keys to this value.
     *
     * <p>
     * Note that this method is identical in functionality to {@link #contains contains} (which predates
     * the {@link Map} interface).
     *
     * @param value
     *        value whose presence in this hashtable is to be tested
     * @return <code>true</code> if this map maps one or more keys to the specified value
     * @throws NullPointerException
     *         if the value is <code>null</code>
     */
    @Override
    public boolean containsValue(Object value) {
        throw new RuntimeException();
    }

    /**
     * Returns an enumeration of the values in this hashtable. Use the Enumeration methods on the
     * returned object to fetch the elements sequentially.
     *
     * @return an enumeration of the values in this hashtable.
     * @see java.util.Enumeration
     * @see #keys()
     * @see #values()
     * @see Map
     */
    @Override
    public Enumeration<V> elements() {
        throw new RuntimeException();
    }

    /**
     * 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 <code>remove</code>
     * operation, or through the <code>setValue</code> 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 <code>Iterator.remove</code>, <code>Set.remove</code>,
     * <code>removeAll</code>, <code>retainAll</code> and <code>clear</code> operations. It does not support the
     * <code>add</code> or <code>addAll</code> operations.
     */
    @Override
    public Set<Map.Entry<K, V>> entrySet() {
        throw new RuntimeException();
    }

    /**
     * Compares the specified Object with this Map for equality, as per the definition in the Map
     * interface.
     *
     * @param o
     *        object to be compared for equality with this hashtable
     * @return true if the specified Object is equal to this Map
     * @see Map#equals(Object)
     */
    @Override
    public boolean equals(@Nullable Object o) {
        throw new RuntimeException();
    }

    /**
     * Returns the value to which the specified key is mapped, or {@code null} if this map contains no
     * mapping for the key.
     *
     * <p>
     * More formally, if this map contains a mapping from a key {@code k} to a value {@code v} such that
     * {@code (key.equals(k))}, then this method returns {@code v}; otherwise it returns {@code null}.
     * (There can be at most one such mapping.)
     *
     * @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 NullPointerException
     *         if the specified key is null
     * @see #put(Object, Object)
     */
    @Override
    @Nullable
    public V get(Object key) {
        throw new RuntimeException();
    }

    /**
     * Returns the hash code value for this Map as per the definition in the Map interface.
     *
     * @see Map#hashCode()
     */
    @Override
    public int hashCode() {
        throw new RuntimeException();
    }

    /**
     * Tests if this hashtable maps no keys to values.
     *
     * @return <code>true</code> if this hashtable maps no keys to values; <code>false</code> otherwise.
     */
    @Override
    public boolean isEmpty() {
        throw new RuntimeException();
    }

    /**
     * Returns an enumeration of the keys in this hashtable.
     *
     * @return an enumeration of the keys in this hashtable.
     * @see Enumeration
     * @see #elements()
     * @see #keySet()
     * @see Map
     */
    @Override
    public Enumeration<K> keys() {
        throw new RuntimeException();
    }

    /**
     * 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 <code>remove</code>
     * operation), the results of the iteration are undefined. The set supports element removal, which
     * removes the corresponding mapping from the map, via the <code>Iterator.remove</code>,
     * <code>Set.remove</code>, <code>removeAll</code>, <code>retainAll</code>, and <code>clear</code> operations. It
     * does not support the <code>add</code> or <code>addAll</code> operations.
     */
    @Override
    public Set<K> keySet() {
        throw new RuntimeException();
    }

    /**
     * Maps the specified <code>key</code> to the specified <code>value</code> in this hashtable.
     * Neither the key nor the value can be <code>null</code>.
     * <p>
     *
     * The value can be retrieved by calling the <code>get</code> method with a key that is equal to the
     * original key.
     *
     * @param key
     *        the hashtable key
     * @param value
     *        the value
     * @return the previous value of the specified key in this hashtable, or <code>null</code> if it did
     *         not have one
     * @exception NullPointerException
     *            if the key or value is <code>null</code>
     * @see Object#equals(Object)
     * @see #get(Object)
     */
    @Override
    @Nullable
    public V put(K key, V value) {
        throw new RuntimeException();
    }

    /**
     * Copies all of the mappings from the specified map to this hashtable. These mappings will replace
     * any mappings that this hashtable had for any of the keys currently in the specified map.
     *
     * @param t
     *        mappings to be stored in this map
     * @throws NullPointerException
     *         if the specified map is null
     */
    @Override
    public void putAll(Map<? extends K, ? extends V> t) {
        throw new RuntimeException();
    }

    /**
     * Increases the capacity of and internally reorganizes this hashtable, in order to accommodate and
     * access its entries more efficiently. This method is called automatically when the number of keys
     * in the hashtable exceeds this hashtable's capacity and load factor.
     */
    protected void rehash() {
        throw new RuntimeException();
    }

    /**
     * Removes the key (and its corresponding value) from this hashtable. This method does nothing if
     * the key is not in the hashtable.
     *
     * @param key
     *        the key that needs to be removed
     * @return the value to which the key had been mapped in this hashtable, or <code>null</code> if the
     *         key did not have a mapping
     * @throws NullPointerException
     *         if the key is <code>null</code>
     */
    @Override
    @Nullable
    public V remove(Object key) {
        throw new RuntimeException();
    }

    /**
     * Returns the number of keys in this hashtable.
     *
     * @return the number of keys in this hashtable.
     */
    @Override
    public int size() {
        throw new RuntimeException();
    }

    /**
     * Returns a string representation of this <code>Hashtable</code> object in the form of a set of
     * entries, enclosed in braces and separated by the ASCII characters "<code>,&nbsp;</code>" (comma and
     * space). Each entry is rendered as the key, an equals sign <code>=</code>, and the associated element,
     * where the <code>toString</code> method is used to convert the key and element to strings.
     *
     * @return a string representation of this hashtable
     */
    @Override
    public String toString() {
        throw new RuntimeException();
    }

    /**
     * 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
     * <code>remove</code> operation), the results of the iteration are undefined. The collection supports
     * element removal, which removes the corresponding mapping from the map, via the
     * <code>Iterator.remove</code>, <code>Collection.remove</code>, <code>removeAll</code>, <code>retainAll</code> and
     * <code>clear</code> operations. It does not support the <code>add</code> or <code>addAll</code> operations.
     */
    @Override
    public Collection<V> values() {
        throw new RuntimeException();
    }
}
