/* 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
