/* List.java -- An ordered collection which allows indexed access
   Copyright (C) 1998, 2001, 2005  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;

/**
 * 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
   * @throws NullPointerException if o is null and this list doesn't support
   *         the addition of null values.
   */
  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
   * @throws NullPointerException if o is null and this list doesn't support
   *         the addition of null values.
   */
  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 some element of c is null and this list
   *         doesn't support the addition of null values.
   * @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
   * @throws NullPointerException if some element of c is null and this list
   *         doesn't support the addition of null values.
   * @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
   * @throws ClassCastException if the type of o is not a valid type
   *         for this list.
   * @throws NullPointerException if o is null and the list doesn't
   *         support null values.
   */
  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
   * @throws ClassCastException if the type of any element in c is not a valid
   *         type for this list.
   * @throws NullPointerException if some element of c is null and this
   *         list does not support null values.
   * @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.
   * @throws ClassCastException if the type of o is not a valid
   *         type for this list.
   * @throws NullPointerException if o is null and this
   *         list does not support null values.
   */
  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.
   * @throws ClassCastException if the type of o is not a valid
   *         type for this list.
   * @throws NullPointerException if o is null and this
   *         list does not support null values.
   */
  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
   * @throws ClassCastException if the type of o is not a valid
   *         type for this list.
   * @throws NullPointerException if o is null and this
   *         list does not support removing null values.
   */
  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
   * @throws ClassCastException if the type of any element in c is not a valid
   *         type for this list.
   * @throws NullPointerException if some element of c is null and this
   *         list does not support removing null values.
   * @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
   * @throws ClassCastException if the type of any element in c is not a valid
   *         type for this list.
   * @throws NullPointerException if some element of c is null and this
   *         list does not support retaining null values.
   * @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
   * @throws NullPointerException if o is null and this
   *         list does not support null values.
   */
  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
   */
  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);
}
