/* Dictionary.java -- an abstract (and essentially worthless)
   class which is Hashtable's superclass
   Copyright (C) 1998, 2001, 2002, 2004 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util;

/**
 * A Dictionary maps keys to values; <i>how</i> it does that is
 * implementation-specific.
 *
 * This is an abstract class which has really gone by the wayside.
 * People at Javasoft are probably embarrassed by it.  At this point,
 * it might as well be an interface rather than a class, but it remains
 * this poor, laughable skeleton for the sake of backwards compatibility.
 * At any rate, this was what came before the {@link Map} interface
 * in the Collections framework.
 *
 * @author Jon Zeppieri
 * @author Eric Blake (ebb9@email.byu.edu)
 * @see Map
 * @see Hashtable
 * @since 1.0
 * @status updated to 1.4
 */
public abstract class Dictionary<K, V>
{
  // WARNING: Dictionary is a CORE class in the bootstrap cycle. See the
  // comments in vm/reference/java/lang/Runtime for implications of this fact.

  /**
   * Sole constructor (often called implicitly).
   */
  public Dictionary()
  {
  }

  /**
   * Returns an Enumeration of the values in this Dictionary.
   *
   * @return an Enumeration of the values
   * @see #keys()
   */
  public abstract Enumeration<V> elements();

  /**
   * Returns the value associated with the supplied key, or null
   * if no such value exists. Since Dictionaries are not allowed null keys
   * or elements, a null result always means the key is not present.
   *
   * @param key the key to use to fetch the value
   * @return the mapped value
   * @throws NullPointerException if key is null
   * @see #put(Object, Object)
   */
  public abstract V get(Object key);

  /**
   * Returns true when there are no elements in this Dictionary.
   *
   * @return <code>size() == 0</code>
   */
  public abstract boolean isEmpty();

  /**
   * Returns an Enumeration of the keys in this Dictionary
   *
   * @return an Enumeration of the keys
   * @see #elements()
   */
  public abstract Enumeration<K> keys();

  /**
   * Inserts a new value into this Dictionary, located by the
   * supplied key. Dictionary does not support null keys or values, so
   * a null return can safely be interpreted as adding a new key.
   *
   * @param key the key which locates the value
   * @param value the value to put into the Dictionary
   * @return the previous value of the key, or null if there was none
   * @throws NullPointerException if key or value is null
   * @see #get(Object)
   */
  public abstract V put(K key, V value);

  /**
   * Removes from the Dictionary the value located by the given key. A null
   * return safely means that the key was not mapped in the Dictionary.
   *
   * @param key the key used to locate the value to be removed
   * @return the value associated with the removed key
   * @throws NullPointerException if key is null
   */
  public abstract V remove(Object key);

  /**
   * Returns the number of values currently in this Dictionary.
   *
   * @return the number of keys in the Dictionary
   */
  public abstract int size();
} // class Dictionary
