Save This Page
Home » openjdk-7 » java » util » [javadoc | source]
    1   /*
    2    * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package java.util;
   27   
   28   /**
   29    * This class provides a skeletal implementation of the {@link List}
   30    * interface to minimize the effort required to implement this interface
   31    * backed by a "random access" data store (such as an array).  For sequential
   32    * access data (such as a linked list), {@link AbstractSequentialList} should
   33    * be used in preference to this class.
   34    *
   35    * <p>To implement an unmodifiable list, the programmer needs only to extend
   36    * this class and provide implementations for the {@link #get(int)} and
   37    * {@link List#size() size()} methods.
   38    *
   39    * <p>To implement a modifiable list, the programmer must additionally
   40    * override the {@link #set(int, Object) set(int, E)} method (which otherwise
   41    * throws an {@code UnsupportedOperationException}).  If the list is
   42    * variable-size the programmer must additionally override the
   43    * {@link #add(int, Object) add(int, E)} and {@link #remove(int)} methods.
   44    *
   45    * <p>The programmer should generally provide a void (no argument) and collection
   46    * constructor, as per the recommendation in the {@link Collection} interface
   47    * specification.
   48    *
   49    * <p>Unlike the other abstract collection implementations, the programmer does
   50    * <i>not</i> have to provide an iterator implementation; the iterator and
   51    * list iterator are implemented by this class, on top of the "random access"
   52    * methods:
   53    * {@link #get(int)},
   54    * {@link #set(int, Object) set(int, E)},
   55    * {@link #add(int, Object) add(int, E)} and
   56    * {@link #remove(int)}.
   57    *
   58    * <p>The documentation for each non-abstract method in this class describes its
   59    * implementation in detail.  Each of these methods may be overridden if the
   60    * collection being implemented admits a more efficient implementation.
   61    *
   62    * <p>This class is a member of the
   63    * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   64    * Java Collections Framework</a>.
   65    *
   66    * @author  Josh Bloch
   67    * @author  Neal Gafter
   68    * @since 1.2
   69    */
   70   
   71   public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
   72       /**
   73        * Sole constructor.  (For invocation by subclass constructors, typically
   74        * implicit.)
   75        */
   76       protected AbstractList() {
   77       }
   78   
   79       /**
   80        * Appends the specified element to the end of this list (optional
   81        * operation).
   82        *
   83        * <p>Lists that support this operation may place limitations on what
   84        * elements may be added to this list.  In particular, some
   85        * lists will refuse to add null elements, and others will impose
   86        * restrictions on the type of elements that may be added.  List
   87        * classes should clearly specify in their documentation any restrictions
   88        * on what elements may be added.
   89        *
   90        * <p>This implementation calls {@code add(size(), e)}.
   91        *
   92        * <p>Note that this implementation throws an
   93        * {@code UnsupportedOperationException} unless
   94        * {@link #add(int, Object) add(int, E)} is overridden.
   95        *
   96        * @param e element to be appended to this list
   97        * @return {@code true} (as specified by {@link Collection#add})
   98        * @throws UnsupportedOperationException if the {@code add} operation
   99        *         is not supported by this list
  100        * @throws ClassCastException if the class of the specified element
  101        *         prevents it from being added to this list
  102        * @throws NullPointerException if the specified element is null and this
  103        *         list does not permit null elements
  104        * @throws IllegalArgumentException if some property of this element
  105        *         prevents it from being added to this list
  106        */
  107       public boolean add(E e) {
  108           add(size(), e);
  109           return true;
  110       }
  111   
  112       /**
  113        * {@inheritDoc}
  114        *
  115        * @throws IndexOutOfBoundsException {@inheritDoc}
  116        */
  117       abstract public E get(int index);
  118   
  119       /**
  120        * {@inheritDoc}
  121        *
  122        * <p>This implementation always throws an
  123        * {@code UnsupportedOperationException}.
  124        *
  125        * @throws UnsupportedOperationException {@inheritDoc}
  126        * @throws ClassCastException            {@inheritDoc}
  127        * @throws NullPointerException          {@inheritDoc}
  128        * @throws IllegalArgumentException      {@inheritDoc}
  129        * @throws IndexOutOfBoundsException     {@inheritDoc}
  130        */
  131       public E set(int index, E element) {
  132           throw new UnsupportedOperationException();
  133       }
  134   
  135       /**
  136        * {@inheritDoc}
  137        *
  138        * <p>This implementation always throws an
  139        * {@code UnsupportedOperationException}.
  140        *
  141        * @throws UnsupportedOperationException {@inheritDoc}
  142        * @throws ClassCastException            {@inheritDoc}
  143        * @throws NullPointerException          {@inheritDoc}
  144        * @throws IllegalArgumentException      {@inheritDoc}
  145        * @throws IndexOutOfBoundsException     {@inheritDoc}
  146        */
  147       public void add(int index, E element) {
  148           throw new UnsupportedOperationException();
  149       }
  150   
  151       /**
  152        * {@inheritDoc}
  153        *
  154        * <p>This implementation always throws an
  155        * {@code UnsupportedOperationException}.
  156        *
  157        * @throws UnsupportedOperationException {@inheritDoc}
  158        * @throws IndexOutOfBoundsException     {@inheritDoc}
  159        */
  160       public E remove(int index) {
  161           throw new UnsupportedOperationException();
  162       }
  163   
  164   
  165       // Search Operations
  166   
  167       /**
  168        * {@inheritDoc}
  169        *
  170        * <p>This implementation first gets a list iterator (with
  171        * {@code listIterator()}).  Then, it iterates over the list until the
  172        * specified element is found or the end of the list is reached.
  173        *
  174        * @throws ClassCastException   {@inheritDoc}
  175        * @throws NullPointerException {@inheritDoc}
  176        */
  177       public int indexOf(Object o) {
  178           ListIterator<E> e = listIterator();
  179           if (o==null) {
  180               while (e.hasNext())
  181                   if (e.next()==null)
  182                       return e.previousIndex();
  183           } else {
  184               while (e.hasNext())
  185                   if (o.equals(e.next()))
  186                       return e.previousIndex();
  187           }
  188           return -1;
  189       }
  190   
  191       /**
  192        * {@inheritDoc}
  193        *
  194        * <p>This implementation first gets a list iterator that points to the end
  195        * of the list (with {@code listIterator(size())}).  Then, it iterates
  196        * backwards over the list until the specified element is found, or the
  197        * beginning of the list is reached.
  198        *
  199        * @throws ClassCastException   {@inheritDoc}
  200        * @throws NullPointerException {@inheritDoc}
  201        */
  202       public int lastIndexOf(Object o) {
  203           ListIterator<E> e = listIterator(size());
  204           if (o==null) {
  205               while (e.hasPrevious())
  206                   if (e.previous()==null)
  207                       return e.nextIndex();
  208           } else {
  209               while (e.hasPrevious())
  210                   if (o.equals(e.previous()))
  211                       return e.nextIndex();
  212           }
  213           return -1;
  214       }
  215   
  216   
  217       // Bulk Operations
  218   
  219       /**
  220        * Removes all of the elements from this list (optional operation).
  221        * The list will be empty after this call returns.
  222        *
  223        * <p>This implementation calls {@code removeRange(0, size())}.
  224        *
  225        * <p>Note that this implementation throws an
  226        * {@code UnsupportedOperationException} unless {@code remove(int
  227        * index)} or {@code removeRange(int fromIndex, int toIndex)} is
  228        * overridden.
  229        *
  230        * @throws UnsupportedOperationException if the {@code clear} operation
  231        *         is not supported by this list
  232        */
  233       public void clear() {
  234           removeRange(0, size());
  235       }
  236   
  237       /**
  238        * {@inheritDoc}
  239        *
  240        * <p>This implementation gets an iterator over the specified collection
  241        * and iterates over it, inserting the elements obtained from the
  242        * iterator into this list at the appropriate position, one at a time,
  243        * using {@code add(int, E)}.
  244        * Many implementations will override this method for efficiency.
  245        *
  246        * <p>Note that this implementation throws an
  247        * {@code UnsupportedOperationException} unless
  248        * {@link #add(int, Object) add(int, E)} is overridden.
  249        *
  250        * @throws UnsupportedOperationException {@inheritDoc}
  251        * @throws ClassCastException            {@inheritDoc}
  252        * @throws NullPointerException          {@inheritDoc}
  253        * @throws IllegalArgumentException      {@inheritDoc}
  254        * @throws IndexOutOfBoundsException     {@inheritDoc}
  255        */
  256       public boolean addAll(int index, Collection<? extends E> c) {
  257           rangeCheckForAdd(index);
  258           boolean modified = false;
  259           Iterator<? extends E> e = c.iterator();
  260           while (e.hasNext()) {
  261               add(index++, e.next());
  262               modified = true;
  263           }
  264           return modified;
  265       }
  266   
  267   
  268       // Iterators
  269   
  270       /**
  271        * Returns an iterator over the elements in this list in proper sequence.
  272        *
  273        * <p>This implementation returns a straightforward implementation of the
  274        * iterator interface, relying on the backing list's {@code size()},
  275        * {@code get(int)}, and {@code remove(int)} methods.
  276        *
  277        * <p>Note that the iterator returned by this method will throw an
  278        * {@link UnsupportedOperationException} in response to its
  279        * {@code remove} method unless the list's {@code remove(int)} method is
  280        * overridden.
  281        *
  282        * <p>This implementation can be made to throw runtime exceptions in the
  283        * face of concurrent modification, as described in the specification
  284        * for the (protected) {@link #modCount} field.
  285        *
  286        * @return an iterator over the elements in this list in proper sequence
  287        */
  288       public Iterator<E> iterator() {
  289           return new Itr();
  290       }
  291   
  292       /**
  293        * {@inheritDoc}
  294        *
  295        * <p>This implementation returns {@code listIterator(0)}.
  296        *
  297        * @see #listIterator(int)
  298        */
  299       public ListIterator<E> listIterator() {
  300           return listIterator(0);
  301       }
  302   
  303       /**
  304        * {@inheritDoc}
  305        *
  306        * <p>This implementation returns a straightforward implementation of the
  307        * {@code ListIterator} interface that extends the implementation of the
  308        * {@code Iterator} interface returned by the {@code iterator()} method.
  309        * The {@code ListIterator} implementation relies on the backing list's
  310        * {@code get(int)}, {@code set(int, E)}, {@code add(int, E)}
  311        * and {@code remove(int)} methods.
  312        *
  313        * <p>Note that the list iterator returned by this implementation will
  314        * throw an {@link UnsupportedOperationException} in response to its
  315        * {@code remove}, {@code set} and {@code add} methods unless the
  316        * list's {@code remove(int)}, {@code set(int, E)}, and
  317        * {@code add(int, E)} methods are overridden.
  318        *
  319        * <p>This implementation can be made to throw runtime exceptions in the
  320        * face of concurrent modification, as described in the specification for
  321        * the (protected) {@link #modCount} field.
  322        *
  323        * @throws IndexOutOfBoundsException {@inheritDoc}
  324        */
  325       public ListIterator<E> listIterator(final int index) {
  326           rangeCheckForAdd(index);
  327   
  328           return new ListItr(index);
  329       }
  330   
  331       private class Itr implements Iterator<E> {
  332           /**
  333            * Index of element to be returned by subsequent call to next.
  334            */
  335           int cursor = 0;
  336   
  337           /**
  338            * Index of element returned by most recent call to next or
  339            * previous.  Reset to -1 if this element is deleted by a call
  340            * to remove.
  341            */
  342           int lastRet = -1;
  343   
  344           /**
  345            * The modCount value that the iterator believes that the backing
  346            * List should have.  If this expectation is violated, the iterator
  347            * has detected concurrent modification.
  348            */
  349           int expectedModCount = modCount;
  350   
  351           public boolean hasNext() {
  352               return cursor != size();
  353           }
  354   
  355           public E next() {
  356               checkForComodification();
  357               try {
  358                   int i = cursor;
  359                   E next = get(i);
  360                   lastRet = i;
  361                   cursor = i + 1;
  362                   return next;
  363               } catch (IndexOutOfBoundsException e) {
  364                   checkForComodification();
  365                   throw new NoSuchElementException();
  366               }
  367           }
  368   
  369           public void remove() {
  370               if (lastRet < 0)
  371                   throw new IllegalStateException();
  372               checkForComodification();
  373   
  374               try {
  375                   AbstractList.this.remove(lastRet);
  376                   if (lastRet < cursor)
  377                       cursor--;
  378                   lastRet = -1;
  379                   expectedModCount = modCount;
  380               } catch (IndexOutOfBoundsException e) {
  381                   throw new ConcurrentModificationException();
  382               }
  383           }
  384   
  385           final void checkForComodification() {
  386               if (modCount != expectedModCount)
  387                   throw new ConcurrentModificationException();
  388           }
  389       }
  390   
  391       private class ListItr extends Itr implements ListIterator<E> {
  392           ListItr(int index) {
  393               cursor = index;
  394           }
  395   
  396           public boolean hasPrevious() {
  397               return cursor != 0;
  398           }
  399   
  400           public E previous() {
  401               checkForComodification();
  402               try {
  403                   int i = cursor - 1;
  404                   E previous = get(i);
  405                   lastRet = cursor = i;
  406                   return previous;
  407               } catch (IndexOutOfBoundsException e) {
  408                   checkForComodification();
  409                   throw new NoSuchElementException();
  410               }
  411           }
  412   
  413           public int nextIndex() {
  414               return cursor;
  415           }
  416   
  417           public int previousIndex() {
  418               return cursor-1;
  419           }
  420   
  421           public void set(E e) {
  422               if (lastRet < 0)
  423                   throw new IllegalStateException();
  424               checkForComodification();
  425   
  426               try {
  427                   AbstractList.this.set(lastRet, e);
  428                   expectedModCount = modCount;
  429               } catch (IndexOutOfBoundsException ex) {
  430                   throw new ConcurrentModificationException();
  431               }
  432           }
  433   
  434           public void add(E e) {
  435               checkForComodification();
  436   
  437               try {
  438                   int i = cursor;
  439                   AbstractList.this.add(i, e);
  440                   lastRet = -1;
  441                   cursor = i + 1;
  442                   expectedModCount = modCount;
  443               } catch (IndexOutOfBoundsException ex) {
  444                   throw new ConcurrentModificationException();
  445               }
  446           }
  447       }
  448   
  449       /**
  450        * {@inheritDoc}
  451        *
  452        * <p>This implementation returns a list that subclasses
  453        * {@code AbstractList}.  The subclass stores, in private fields, the
  454        * offset of the subList within the backing list, the size of the subList
  455        * (which can change over its lifetime), and the expected
  456        * {@code modCount} value of the backing list.  There are two variants
  457        * of the subclass, one of which implements {@code RandomAccess}.
  458        * If this list implements {@code RandomAccess} the returned list will
  459        * be an instance of the subclass that implements {@code RandomAccess}.
  460        *
  461        * <p>The subclass's {@code set(int, E)}, {@code get(int)},
  462        * {@code add(int, E)}, {@code remove(int)}, {@code addAll(int,
  463        * Collection)} and {@code removeRange(int, int)} methods all
  464        * delegate to the corresponding methods on the backing abstract list,
  465        * after bounds-checking the index and adjusting for the offset.  The
  466        * {@code addAll(Collection c)} method merely returns {@code addAll(size,
  467        * c)}.
  468        *
  469        * <p>The {@code listIterator(int)} method returns a "wrapper object"
  470        * over a list iterator on the backing list, which is created with the
  471        * corresponding method on the backing list.  The {@code iterator} method
  472        * merely returns {@code listIterator()}, and the {@code size} method
  473        * merely returns the subclass's {@code size} field.
  474        *
  475        * <p>All methods first check to see if the actual {@code modCount} of
  476        * the backing list is equal to its expected value, and throw a
  477        * {@code ConcurrentModificationException} if it is not.
  478        *
  479        * @throws IndexOutOfBoundsException if an endpoint index value is out of range
  480        *         {@code (fromIndex < 0 || toIndex > size)}
  481        * @throws IllegalArgumentException if the endpoint indices are out of order
  482        *         {@code (fromIndex > toIndex)}
  483        */
  484       public List<E> subList(int fromIndex, int toIndex) {
  485           return (this instanceof RandomAccess ?
  486                   new RandomAccessSubList<E>(this, fromIndex, toIndex) :
  487                   new SubList<E>(this, fromIndex, toIndex));
  488       }
  489   
  490       // Comparison and hashing
  491   
  492       /**
  493        * Compares the specified object with this list for equality.  Returns
  494        * {@code true} if and only if the specified object is also a list, both
  495        * lists have the same size, and all corresponding pairs of elements in
  496        * the two lists are <i>equal</i>.  (Two elements {@code e1} and
  497        * {@code e2} are <i>equal</i> if {@code (e1==null ? e2==null :
  498        * e1.equals(e2))}.)  In other words, two lists are defined to be
  499        * equal if they contain the same elements in the same order.<p>
  500        *
  501        * This implementation first checks if the specified object is this
  502        * list. If so, it returns {@code true}; if not, it checks if the
  503        * specified object is a list. If not, it returns {@code false}; if so,
  504        * it iterates over both lists, comparing corresponding pairs of elements.
  505        * If any comparison returns {@code false}, this method returns
  506        * {@code false}.  If either iterator runs out of elements before the
  507        * other it returns {@code false} (as the lists are of unequal length);
  508        * otherwise it returns {@code true} when the iterations complete.
  509        *
  510        * @param o the object to be compared for equality with this list
  511        * @return {@code true} if the specified object is equal to this list
  512        */
  513       public boolean equals(Object o) {
  514           if (o == this)
  515               return true;
  516           if (!(o instanceof List))
  517               return false;
  518   
  519           ListIterator<E> e1 = listIterator();
  520           ListIterator e2 = ((List) o).listIterator();
  521           while(e1.hasNext() && e2.hasNext()) {
  522               E o1 = e1.next();
  523               Object o2 = e2.next();
  524               if (!(o1==null ? o2==null : o1.equals(o2)))
  525                   return false;
  526           }
  527           return !(e1.hasNext() || e2.hasNext());
  528       }
  529   
  530       /**
  531        * Returns the hash code value for this list.
  532        *
  533        * <p>This implementation uses exactly the code that is used to define the
  534        * list hash function in the documentation for the {@link List#hashCode}
  535        * method.
  536        *
  537        * @return the hash code value for this list
  538        */
  539       public int hashCode() {
  540           int hashCode = 1;
  541           for (E e : this)
  542               hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
  543           return hashCode;
  544       }
  545   
  546       /**
  547        * Removes from this list all of the elements whose index is between
  548        * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
  549        * Shifts any succeeding elements to the left (reduces their index).
  550        * This call shortens the list by {@code (toIndex - fromIndex)} elements.
  551        * (If {@code toIndex==fromIndex}, this operation has no effect.)
  552        *
  553        * <p>This method is called by the {@code clear} operation on this list
  554        * and its subLists.  Overriding this method to take advantage of
  555        * the internals of the list implementation can <i>substantially</i>
  556        * improve the performance of the {@code clear} operation on this list
  557        * and its subLists.
  558        *
  559        * <p>This implementation gets a list iterator positioned before
  560        * {@code fromIndex}, and repeatedly calls {@code ListIterator.next}
  561        * followed by {@code ListIterator.remove} until the entire range has
  562        * been removed.  <b>Note: if {@code ListIterator.remove} requires linear
  563        * time, this implementation requires quadratic time.</b>
  564        *
  565        * @param fromIndex index of first element to be removed
  566        * @param toIndex index after last element to be removed
  567        */
  568       protected void removeRange(int fromIndex, int toIndex) {
  569           ListIterator<E> it = listIterator(fromIndex);
  570           for (int i=0, n=toIndex-fromIndex; i<n; i++) {
  571               it.next();
  572               it.remove();
  573           }
  574       }
  575   
  576       /**
  577        * The number of times this list has been <i>structurally modified</i>.
  578        * Structural modifications are those that change the size of the
  579        * list, or otherwise perturb it in such a fashion that iterations in
  580        * progress may yield incorrect results.
  581        *
  582        * <p>This field is used by the iterator and list iterator implementation
  583        * returned by the {@code iterator} and {@code listIterator} methods.
  584        * If the value of this field changes unexpectedly, the iterator (or list
  585        * iterator) will throw a {@code ConcurrentModificationException} in
  586        * response to the {@code next}, {@code remove}, {@code previous},
  587        * {@code set} or {@code add} operations.  This provides
  588        * <i>fail-fast</i> behavior, rather than non-deterministic behavior in
  589        * the face of concurrent modification during iteration.
  590        *
  591        * <p><b>Use of this field by subclasses is optional.</b> If a subclass
  592        * wishes to provide fail-fast iterators (and list iterators), then it
  593        * merely has to increment this field in its {@code add(int, E)} and
  594        * {@code remove(int)} methods (and any other methods that it overrides
  595        * that result in structural modifications to the list).  A single call to
  596        * {@code add(int, E)} or {@code remove(int)} must add no more than
  597        * one to this field, or the iterators (and list iterators) will throw
  598        * bogus {@code ConcurrentModificationExceptions}.  If an implementation
  599        * does not wish to provide fail-fast iterators, this field may be
  600        * ignored.
  601        */
  602       protected transient int modCount = 0;
  603   
  604       private void rangeCheckForAdd(int index) {
  605           if (index < 0 || index > size())
  606               throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  607       }
  608   
  609       private String outOfBoundsMsg(int index) {
  610           return "Index: "+index+", Size: "+size();
  611       }
  612   }
  613   
  614   class SubList<E> extends AbstractList<E> {
  615       private final AbstractList<E> l;
  616       private final int offset;
  617       private int size;
  618   
  619       SubList(AbstractList<E> list, int fromIndex, int toIndex) {
  620           if (fromIndex < 0)
  621               throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
  622           if (toIndex > list.size())
  623               throw new IndexOutOfBoundsException("toIndex = " + toIndex);
  624           if (fromIndex > toIndex)
  625               throw new IllegalArgumentException("fromIndex(" + fromIndex +
  626                                                  ") > toIndex(" + toIndex + ")");
  627           l = list;
  628           offset = fromIndex;
  629           size = toIndex - fromIndex;
  630           this.modCount = l.modCount;
  631       }
  632   
  633       public E set(int index, E element) {
  634           rangeCheck(index);
  635           checkForComodification();
  636           return l.set(index+offset, element);
  637       }
  638   
  639       public E get(int index) {
  640           rangeCheck(index);
  641           checkForComodification();
  642           return l.get(index+offset);
  643       }
  644   
  645       public int size() {
  646           checkForComodification();
  647           return size;
  648       }
  649   
  650       public void add(int index, E element) {
  651           rangeCheckForAdd(index);
  652           checkForComodification();
  653           l.add(index+offset, element);
  654           this.modCount = l.modCount;
  655           size++;
  656       }
  657   
  658       public E remove(int index) {
  659           rangeCheck(index);
  660           checkForComodification();
  661           E result = l.remove(index+offset);
  662           this.modCount = l.modCount;
  663           size--;
  664           return result;
  665       }
  666   
  667       protected void removeRange(int fromIndex, int toIndex) {
  668           checkForComodification();
  669           l.removeRange(fromIndex+offset, toIndex+offset);
  670           this.modCount = l.modCount;
  671           size -= (toIndex-fromIndex);
  672       }
  673   
  674       public boolean addAll(Collection<? extends E> c) {
  675           return addAll(size, c);
  676       }
  677   
  678       public boolean addAll(int index, Collection<? extends E> c) {
  679           rangeCheckForAdd(index);
  680           int cSize = c.size();
  681           if (cSize==0)
  682               return false;
  683   
  684           checkForComodification();
  685           l.addAll(offset+index, c);
  686           this.modCount = l.modCount;
  687           size += cSize;
  688           return true;
  689       }
  690   
  691       public Iterator<E> iterator() {
  692           return listIterator();
  693       }
  694   
  695       public ListIterator<E> listIterator(final int index) {
  696           checkForComodification();
  697           rangeCheckForAdd(index);
  698   
  699           return new ListIterator<E>() {
  700               private final ListIterator<E> i = l.listIterator(index+offset);
  701   
  702               public boolean hasNext() {
  703                   return nextIndex() < size;
  704               }
  705   
  706               public E next() {
  707                   if (hasNext())
  708                       return i.next();
  709                   else
  710                       throw new NoSuchElementException();
  711               }
  712   
  713               public boolean hasPrevious() {
  714                   return previousIndex() >= 0;
  715               }
  716   
  717               public E previous() {
  718                   if (hasPrevious())
  719                       return i.previous();
  720                   else
  721                       throw new NoSuchElementException();
  722               }
  723   
  724               public int nextIndex() {
  725                   return i.nextIndex() - offset;
  726               }
  727   
  728               public int previousIndex() {
  729                   return i.previousIndex() - offset;
  730               }
  731   
  732               public void remove() {
  733                   i.remove();
  734                   SubList.this.modCount = l.modCount;
  735                   size--;
  736               }
  737   
  738               public void set(E e) {
  739                   i.set(e);
  740               }
  741   
  742               public void add(E e) {
  743                   i.add(e);
  744                   SubList.this.modCount = l.modCount;
  745                   size++;
  746               }
  747           };
  748       }
  749   
  750       public List<E> subList(int fromIndex, int toIndex) {
  751           return new SubList<E>(this, fromIndex, toIndex);
  752       }
  753   
  754       private void rangeCheck(int index) {
  755           if (index < 0 || index >= size)
  756               throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  757       }
  758   
  759       private void rangeCheckForAdd(int index) {
  760           if (index < 0 || index > size)
  761               throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  762       }
  763   
  764       private String outOfBoundsMsg(int index) {
  765           return "Index: "+index+", Size: "+size;
  766       }
  767   
  768       private void checkForComodification() {
  769           if (this.modCount != l.modCount)
  770               throw new ConcurrentModificationException();
  771       }
  772   }
  773   
  774   class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
  775       RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
  776           super(list, fromIndex, toIndex);
  777       }
  778   
  779       public List<E> subList(int fromIndex, int toIndex) {
  780           return new RandomAccessSubList<E>(this, fromIndex, toIndex);
  781       }
  782   }

Save This Page
Home » openjdk-7 » java » util » [javadoc | source]