/* List.java -- An ordered collection which allows indexed access
   Copyright (C) 1998, 2001 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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;

/**
 * An ordered collection (also known as a list). This collection allows
 * access to elements by position, as well as control on where elements
 * are inserted. Unlike sets, duplicate elements are permitted by this
 * general contract (if a subclass forbids duplicates, this should be
 * documented).
 * <p>
 *
 * List places additional requirements on <code>iterator</code>,
 * <code>add</code>, <code>remove</code>, <code>equals</code>, and
 * <code>hashCode</code>, in addition to requiring more methods. List
 * indexing is 0-based (like arrays), although some implementations may
 * require time proportional to the index to obtain an arbitrary element.
 * The List interface is incompatible with Set; you cannot implement both
 * simultaneously.
 * <p>
 *
 * Lists also provide a <code>ListIterator</code> which allows bidirectional
 * traversal and other features atop regular iterators. Lists can be
 * searched for arbitrary elements, and allow easy insertion and removal
 * of multiple elements in one method call.
 * <p>
 *
 * Note: While lists may contain themselves as elements, this leads to
 * undefined (usually infinite recursive) behavior for some methods like
 * hashCode or equals.
 *
 * @author Original author unknown
 * @author Eric Blake <ebb9@email.byu.edu>
 * @see Collection
 * @see Set
 * @see ArrayList
 * @see LinkedList
 * @see Vector
 * @see Arrays#asList(Object[])
 * @see Collections#nCopies(int, Object)
 * @see Collections#EMPTY_LIST
 * @see AbstractList
 * @see AbstractSequentialList
 * @since 1.2
 * @status updated to 1.4
 */
public interface List extends Collection
{
  /**
   * Insert an element into the list at a given position (optional operation).
   * This shifts all existing elements from that position to the end one
   * index to the right. This version of add has no return, since it is
   * assumed to always succeed if there is no exception.
   *
   * @param index the location to insert the item
   * @param o the object to insert
   * @throws UnsupportedOperationException if this list does not support the
   *         add operation
   * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
   * @throws ClassCastException if o cannot be added to this list due to its
   *         type
   * @throws IllegalArgumentException if o cannot be added to this list for
   *         some other reason
   */
  void add(int index, Object o);

  /**
   * Add an element to the end of the list (optional operation). If the list
   * imposes restraints on what can be inserted, such as no null elements,
   * this should be documented.
   *
   * @param o the object to add
   * @return true, as defined by Collection for a modified list
   * @throws UnsupportedOperationException if this list does not support the
   *         add operation
   * @throws ClassCastException if o cannot be added to this list due to its
   *         type
   * @throws IllegalArgumentException if o cannot be added to this list for
   *         some other reason
   */
  boolean add(Object o);

  /**
   * Insert the contents of a collection into the list at a given position
   * (optional operation). Shift all elements at that position to the right
   * by the number of elements inserted. This operation is undefined if
   * this list is modified during the operation (for example, if you try
   * to insert a list into itself).
   *
   * @param index the location to insert the collection
   * @param c the collection to insert
   * @return true if the list was modified by this action, that is, if c is
   *         non-empty
   * @throws UnsupportedOperationException if this list does not support the
   *         addAll operation
   * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
   * @throws ClassCastException if some element of c cannot be added to this
   *         list due to its type
   * @throws IllegalArgumentException if some element of c cannot be added
   *         to this list for some other reason
   * @throws NullPointerException if the specified collection is null
   * @see #add(int, Object)
   */
  boolean addAll(int index, Collection c);

  /**
   * Add the contents of a collection to the end of the list (optional
   * operation).  This operation is undefined if this list is modified
   * during the operation (for example, if you try to insert a list into
   * itself).
   *
   * @param c the collection to add
   * @return true if the list was modified by this action, that is, if c is
   *         non-empty
   * @throws UnsupportedOperationException if this list does not support the
   *         addAll operation
   * @throws ClassCastException if some element of c cannot be added to this
   *         list due to its type
   * @throws IllegalArgumentException if some element of c cannot be added
   *         to this list for some other reason
   * @throws NullPointerException if the specified collection is null
   * @see #add(Object)
   */
  boolean addAll(Collection c);

  /**
   * Clear the list, such that a subsequent call to isEmpty() would return
   * true (optional operation).
   *
   * @throws UnsupportedOperationException if this list does not support the
   *         clear operation
   */
  void clear();

  /**
   * Test whether this list contains a given object as one of its elements.
   * This is defined as the existence of an element e such that
   * <code>o == null ? e == null : o.equals(e)</code>.
   *
   * @param o the element to look for
   * @return true if this list contains the element
   */
  boolean contains(Object o);

  /**
   * Test whether this list contains every element in a given collection.
   *
   * @param c the collection to test for
   * @return true if for every element o in c, contains(o) would return true
   * @throws NullPointerException if the collection is null
   * @see #contains(Object)
   */
  boolean containsAll(Collection c);

  /**
   * Test whether this list is equal to another object. A List is defined to be
   * equal to an object if and only if that object is also a List, and the two
   * lists have the same sequence. Two lists l1 and l2 are equal if and only
   * if <code>l1.size() == l2.size()</code>, and for every integer n between 0
   * and <code>l1.size() - 1</code> inclusive, <code>l1.get(n) == null ?
   * l2.get(n) == null : l1.get(n).equals(l2.get(n))</code>.
   *
   * @param o the object to test for equality with this list
   * @return true if o is equal to this list
   * @see Object#equals(Object)
   * @see #hashCode()
   */
  boolean equals(Object o);

  /**
   * Get the element at a given index in this list.
   *
   * @param index the index of the element to be returned
   * @return the element at index index in this list
   * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
   */
  Object get(int index);

  /**
   * Obtains a hash code for this list. In order to obey the general
   * contract of the hashCode method of class Object, this value is
   * calculated as follows:
   * 
<p><pre>hashCode = 1;
Iterator i = list.iterator();
while (i.hasNext())
{
  Object obj = i.next();
  hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
}</pre>
   *
   * <p>This ensures that the general contract of Object.hashCode()
   * is adhered to.
   *
   * @return the hash code of this list
   * @see Object#hashCode()
   * @see #equals(Object)
   */
  int hashCode();

  /**
   * Obtain the first index at which a given object is to be found in this
   * list.
   *
   * @param o the object to search for
   * @return the least integer n such that <code>o == null ? get(n) == null :
   *         o.equals(get(n))</code>, or -1 if there is no such index
   */
  int indexOf(Object o);

  /**
   * Test whether this list is empty, that is, if size() == 0.
   *
   * @return true if this list contains no elements
   */
  boolean isEmpty();

  /**
   * Obtain an Iterator over this list, whose sequence is the list order.
   *
   * @return an Iterator over the elements of this list, in order
   */
  Iterator iterator();

  /**
   * Obtain the last index at which a given object is to be found in this
   * list.
   *
   * @return the greatest integer n such that <code>o == null ? get(n) == null
   *         : o.equals(get(n))</code>, or -1 if there is no such index
   */
  int lastIndexOf(Object o);

  /**
   * Obtain a ListIterator over this list, starting at the beginning.
   *
   * @return a ListIterator over the elements of this list, in order, starting
   *         at the beginning
   */
  ListIterator listIterator();

  /**
   * Obtain a ListIterator over this list, starting at a given position.
   * A first call to next() would return the same as get(index), and a
   * first call to previous() would return the same as get(index - 1).
   *
   * @param index the position, between 0 and size() inclusive, to begin the
   *        iteration from
   * @return a ListIterator over the elements of this list, in order, starting
   *         at index
   * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
   */
  ListIterator listIterator(int index);

  /**
   * Remove the element at a given position in this list (optional operation).
   * Shifts all remaining elements to the left to fill the gap.
   *
   * @param index the position within the list of the object to remove
   * @return the object that was removed
   * @throws UnsupportedOperationException if this list does not support the
   *         remove operation
   * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
   */
  Object remove(int index);

  /**
   * Remove the first occurence of an object from this list (optional
   * operation). That is, remove the first element e such that
   * <code>o == null ? e == null : o.equals(e)</code>.
   *
   * @param o the object to remove
   * @return true if the list changed as a result of this call, that is, if
   *         the list contained at least one occurrence of o
   * @throws UnsupportedOperationException if this list does not support the
   *         remove operation
   */
  boolean remove(Object o);

  /**
   * Remove all elements of a given collection from this list (optional
   * operation). That is, remove every element e such that c.contains(e).
   *
   * @param c the collection to filter out
   * @return true if this list was modified as a result of this call
   * @throws UnsupportedOperationException if this list does not support the
   *         removeAll operation
   * @throws NullPointerException if the collection is null
   * @see #remove(Object)
   * @see #contains(Object)
   */
  boolean removeAll(Collection c);

  /**
   * Remove all elements of this list that are not contained in a given
   * collection (optional operation). That is, remove every element e such
   * that !c.contains(e).
   *
   * @param c the collection to retain
   * @return true if this list was modified as a result of this call
   * @throws UnsupportedOperationException if this list does not support the
   *         retainAll operation
   * @throws NullPointerException if the collection is null
   * @see #remove(Object)
   * @see #contains(Object)
   */
  boolean retainAll(Collection c);

  /**
   * Replace an element of this list with another object (optional operation).
   *
   * @param index the position within this list of the element to be replaced
   * @param o the object to replace it with
   * @return the object that was replaced
   * @throws UnsupportedOperationException if this list does not support the
   *         set operation
   * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
   * @throws ClassCastException if o cannot be added to this list due to its
   *         type
   * @throws IllegalArgumentException if o cannot be added to this list for
   *         some other reason
   */
  Object set(int index, Object o);

  /**
   * Get the number of elements in this list. If the list contains more
   * than Integer.MAX_VALUE elements, return Integer.MAX_VALUE.
   *
   * @return the number of elements in the list
   */
  int size();

  /**
   * Obtain a List view of a subsection of this list, from fromIndex
   * (inclusive) to toIndex (exclusive). If the two indices are equal, the
   * sublist is empty. The returned list should be modifiable if and only
   * if this list is modifiable. Changes to the returned list should be
   * reflected in this list. If this list is structurally modified in
   * any way other than through the returned list, the result of any subsequent
   * operations on the returned list is undefined.
   *
   * @param fromIndex the index that the returned list should start from
   *        (inclusive)
   * @param toIndex the index that the returned list should go to (exclusive)
   * @return a List backed by a subsection of this list
   * @throws IndexOutOfBoundsException if fromIndex &lt; 0
   *         || toIndex &gt; size() || fromIndex &gt; toIndex
   * @throws IllegalArgumentException if fromIndex &gt; toIndex (according to
   *         AbstractList). Don't you love Sun's inconsistent specifications?
   */
  List subList(int fromIndex, int toIndex);

  /**
   * Copy the current contents of this list into an array.
   *
   * @return an array of type Object[] and length equal to the length of this
   *         list, containing the elements currently in this list, in order
   */
  Object[] toArray();

  /**
   * Copy the current contents of this list into an array. If the array passed
   * as an argument has length less than that of this list, an array of the
   * same run-time type as a, and length equal to the length of this list, is
   * allocated using Reflection. Otherwise, a itself is used. The elements of
   * this list are copied into it, and if there is space in the array, the
   * following element is set to null. The resultant array is returned.
   * Note: The fact that the following element is set to null is only useful
   * if it is known that this list does not contain any null elements.
   *
   * @param a the array to copy this list into
   * @return an array containing the elements currently in this list, in
   *         order
   * @throws ArrayStoreException if the type of any element of the
   *         collection is not a subtype of the element type of a
   * @throws NullPointerException if the specified array is null
   */
  Object[] toArray(Object[] a);
}
