[cvs] / jsr166 / src / main / java / util / Vector.java Repository:
ViewVC logotype

Diff of /jsr166/src/main/java/util/Vector.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.21, Sun May 20 07:54:01 2007 UTC revision 1.22, Tue Sep 11 15:38:19 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright 1994-2006 Sun Microsystems, Inc.  All Rights Reserved.   * Copyright 1994-2007 Sun Microsystems, Inc.  All Rights Reserved.
3   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.   * 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   * This code is free software; you can redistribute it and/or modify it
# Line 41  Line 41 
41   * capacity of a vector before inserting a large number of   * capacity of a vector before inserting a large number of
42   * components; this reduces the amount of incremental reallocation.   * components; this reduces the amount of incremental reallocation.
43   *   *
44   * <p>The Iterators returned by Vector's iterator and listIterator   * <p><a name="fail-fast"/>
45   * methods are <em>fail-fast</em>: if the Vector is structurally modified   * The iterators returned by this class's {@link #iterator() iterator} and
46   * at any time after the Iterator is created, in any way except through the   * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
47   * Iterator's own remove or add methods, the Iterator will throw a   * if the vector is structurally modified at any time after the iterator is
48   * ConcurrentModificationException.  Thus, in the face of concurrent   * created, in any way except through the iterator's own
49   * modification, the Iterator fails quickly and cleanly, rather than risking   * {@link ListIterator#remove() remove} or
50   * arbitrary, non-deterministic behavior at an undetermined time in the future.   * {@link ListIterator#add(Object) add} methods, the iterator will throw a
51   * The Enumerations returned by Vector's elements method are <em>not</em>   * {@link ConcurrentModificationException}.  Thus, in the face of
52   * fail-fast.   * concurrent modification, the iterator fails quickly and cleanly, rather
53     * than risking arbitrary, non-deterministic behavior at an undetermined
54     * time in the future.  The {@link Enumeration Enumerations} returned by
55     * the {@link #elements() elements} method are <em>not</em> fail-fast.
56   *   *
57   * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed   * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
58   * as it is, generally speaking, impossible to make any hard guarantees in the   * as it is, generally speaking, impossible to make any hard guarantees in the
# Line 317  Line 320 
320              public E nextElement() {              public E nextElement() {
321                  synchronized (Vector.this) {                  synchronized (Vector.this) {
322                      if (count < elementCount) {                      if (count < elementCount) {
323                          return (E)elementData[count++];                          return elementData(count++);
324                      }                      }
325                  }                  }
326                  throw new NoSuchElementException("Vector Enumeration");                  throw new NoSuchElementException("Vector Enumeration");
# Line 445  Line 448 
448              throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);              throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
449          }          }
450    
451          return (E)elementData[index];          return elementData(index);
452      }      }
453    
454      /**      /**
# Line 459  Line 462 
462          if (elementCount == 0) {          if (elementCount == 0) {
463              throw new NoSuchElementException();              throw new NoSuchElementException();
464          }          }
465          return (E)elementData[0];          return elementData(0);
466      }      }
467    
468      /**      /**
# Line 473  Line 476 
476          if (elementCount == 0) {          if (elementCount == 0) {
477              throw new NoSuchElementException();              throw new NoSuchElementException();
478          }          }
479          return (E)elementData[elementCount - 1];          return elementData(elementCount - 1);
480      }      }
481    
482      /**      /**
# Line 641  Line 644 
644       */       */
645      public synchronized Object clone() {      public synchronized Object clone() {
646          try {          try {
647                @SuppressWarnings("unchecked")
648              Vector<E> v = (Vector<E>) super.clone();              Vector<E> v = (Vector<E>) super.clone();
649              v.elementData = Arrays.copyOf(elementData, elementCount);              v.elementData = Arrays.copyOf(elementData, elementCount);
650              v.modCount = 0;              v.modCount = 0;
# Line 684  Line 688 
688       * @throws NullPointerException if the given array is null       * @throws NullPointerException if the given array is null
689       * @since 1.2       * @since 1.2
690       */       */
691        @SuppressWarnings("unchecked")
692      public synchronized <T> T[] toArray(T[] a) {      public synchronized <T> T[] toArray(T[] a) {
693          if (a.length < elementCount)          if (a.length < elementCount)
694              return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());              return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
# Line 698  Line 703 
703    
704      // Positional Access Operations      // Positional Access Operations
705    
706        @SuppressWarnings("unchecked")
707        E elementData(int index) {
708            return (E) elementData[index];
709        }
710    
711      /**      /**
712       * Returns the element at the specified position in this Vector.       * Returns the element at the specified position in this Vector.
713       *       *
# Line 711  Line 721 
721          if (index >= elementCount)          if (index >= elementCount)
722              throw new ArrayIndexOutOfBoundsException(index);              throw new ArrayIndexOutOfBoundsException(index);
723    
724          return (E)elementData[index];          return elementData(index);
725      }      }
726    
727      /**      /**
# Line 729  Line 739 
739          if (index >= elementCount)          if (index >= elementCount)
740              throw new ArrayIndexOutOfBoundsException(index);              throw new ArrayIndexOutOfBoundsException(index);
741    
742          Object oldValue = elementData[index];          E oldValue = elementData(index);
743          elementData[index] = element;          elementData[index] = element;
744          return (E)oldValue;          return oldValue;
745      }      }
746    
747      /**      /**
# Line 793  Line 803 
803          modCount++;          modCount++;
804          if (index >= elementCount)          if (index >= elementCount)
805              throw new ArrayIndexOutOfBoundsException(index);              throw new ArrayIndexOutOfBoundsException(index);
806          Object oldValue = elementData[index];          E oldValue = elementData(index);
807    
808          int numMoved = elementCount - index - 1;          int numMoved = elementCount - index - 1;
809          if (numMoved > 0)          if (numMoved > 0)
# Line 801  Line 811 
811                               numMoved);                               numMoved);
812          elementData[--elementCount] = null; // Let gc do its work          elementData[--elementCount] = null; // Let gc do its work
813    
814          return (E)oldValue;          return oldValue;
815      }      }
816    
817      /**      /**
# Line 959  Line 969 
969      }      }
970    
971      /**      /**
972       * Removes from this List all of the elements whose index is between       * Returns a view of the portion of this List between fromIndex,
973       * fromIndex, inclusive and toIndex, exclusive.  Shifts any succeeding       * inclusive, and toIndex, exclusive.  (If fromIndex and toIndex are
974       * elements to the left (reduces their index).       * equal, the returned List is empty.)  The returned List is backed by this
975       * This call shortens the Vector by (toIndex - fromIndex) elements.  (If       * List, so changes in the returned List are reflected in this List, and
976       * toIndex==fromIndex, this operation has no effect.)       * vice-versa.  The returned List supports all of the optional List
977         * operations supported by this List.
978         *
979         * <p>This method eliminates the need for explicit range operations (of
980         * the sort that commonly exist for arrays).  Any operation that expects
981         * a List can be used as a range operation by operating on a subList view
982         * instead of a whole List.  For example, the following idiom
983         * removes a range of elements from a List:
984         * <pre>
985         *      list.subList(from, to).clear();
986         * </pre>
987         * Similar idioms may be constructed for indexOf and lastIndexOf,
988         * and all of the algorithms in the Collections class can be applied to
989         * a subList.
990         *
991         * <p>The semantics of the List returned by this method become undefined if
992         * the backing list (i.e., this List) is <i>structurally modified</i> in
993         * any way other than via the returned List.  (Structural modifications are
994         * those that change the size of the List, or otherwise perturb it in such
995         * a fashion that iterations in progress may yield incorrect results.)
996       *       *
997       * @param fromIndex index of first element to be removed       * @param fromIndex low endpoint (inclusive) of the subList
998       * @param toIndex index after last element to be removed       * @param toIndex high endpoint (exclusive) of the subList
999         * @return a view of the specified range within this List
1000         * @throws IndexOutOfBoundsException if an endpoint index value is out of range
1001         *         {@code (fromIndex < 0 || toIndex > size)}
1002         * @throws IllegalArgumentException if the endpoint indices are out of order
1003         *         {@code (fromIndex > toIndex)}
1004         */
1005        public synchronized List<E> subList(int fromIndex, int toIndex) {
1006            return Collections.synchronizedList(super.subList(fromIndex, toIndex),
1007                                                this);
1008        }
1009    
1010        /**
1011         * Removes from this list all of the elements whose index is between
1012         * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
1013         * Shifts any succeeding elements to the left (reduces their index).
1014         * This call shortens the list by {@code (toIndex - fromIndex)} elements.
1015         * (If {@code toIndex==fromIndex}, this operation has no effect.)
1016       */       */
1017      protected synchronized void removeRange(int fromIndex, int toIndex) {      protected synchronized void removeRange(int fromIndex, int toIndex) {
1018          modCount++;          modCount++;
# Line 992  Line 1038 
1038      }      }
1039    
1040      /**      /**
1041       * Returns a list-iterator of the elements in this list (in proper       * Returns a list iterator over the elements in this list (in proper
1042       * sequence), starting at the specified position in the list.       * sequence), starting at the specified position in the list.
1043       * Obeys the general contract of {@link List#listIterator(int)}.       * The specified index indicates the first element that would be
1044         * returned by an initial call to {@link ListIterator#next next}.
1045         * An initial call to {@link ListIterator#previous previous} would
1046         * return the element with the specified index minus one.
1047       *       *
1048       * <p>The list-iterator is <i>fail-fast</i>: if the list is structurally       * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
      * modified at any time after the Iterator is created, in any way except  
      * through the list-iterator's own {@code remove} or {@code add}  
      * methods, the list-iterator will throw a  
      * {@code ConcurrentModificationException}.  Thus, in the face of  
      * concurrent modification, the iterator fails quickly and cleanly, rather  
      * than risking arbitrary, non-deterministic behavior at an undetermined  
      * time in the future.  
1049       *       *
      * @param index index of the first element to be returned from the  
      *        list-iterator (by a call to {@link ListIterator#next})  
      * @return a list-iterator of the elements in this list (in proper  
      *         sequence), starting at the specified position in the list  
1050       * @throws IndexOutOfBoundsException {@inheritDoc}       * @throws IndexOutOfBoundsException {@inheritDoc}
1051       */       */
1052      public synchronized ListIterator<E> listIterator(int index) {      public synchronized ListIterator<E> listIterator(int index) {
1053          if (index < 0 || index > elementCount)          if (index < 0 || index > elementCount)
1054              throw new IndexOutOfBoundsException("Index: "+index);              throw new IndexOutOfBoundsException("Index: "+index);
1055          return new VectorIterator(index, elementCount);          return new ListItr(index);
1056      }      }
1057    
1058      /**      /**
1059       * {@inheritDoc}       * Returns a list iterator over the elements in this list (in proper
1060         * sequence).
1061         *
1062         * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1063         *
1064         * @see #listIterator(int)
1065       */       */
1066      public synchronized ListIterator<E> listIterator() {      public synchronized ListIterator<E> listIterator() {
1067          return new VectorIterator(0, elementCount);          return new ListItr(0);
1068      }      }
1069    
1070      /**      /**
1071       * Returns an iterator over the elements in this list in proper sequence.       * Returns an iterator over the elements in this list in proper sequence.
1072       *       *
1073         * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1074         *
1075       * @return an iterator over the elements in this list in proper sequence       * @return an iterator over the elements in this list in proper sequence
1076       */       */
1077      public synchronized Iterator<E> iterator() {      public synchronized Iterator<E> iterator() {
1078          return new VectorIterator(0, elementCount);          return new Itr();
1079      }      }
1080    
1081      /**      /**
1082       * Helper method to access array elements under synchronization by       * An optimized version of AbstractList.Itr
      * iterators. The caller performs index check with respect to  
      * expected bounds, so errors accessing the element are reported  
      * as ConcurrentModificationExceptions.  
1083       */       */
1084      final synchronized Object iteratorGet(int index, int expectedModCount) {      private class Itr implements Iterator<E> {
1085          if (modCount == expectedModCount) {          int cursor;       // index of next element to return
1086              try {          int lastRet = -1; // index of last element returned; -1 if no such
1087                  return elementData[index];          int expectedModCount = modCount;
             } catch(IndexOutOfBoundsException fallThrough) {  
             }  
         }  
         throw new ConcurrentModificationException();  
     }  
   
     /**  
      * Streamlined specialization of AbstractList version of iterator.  
      * Locally performs bounds checks, but relies on outer Vector  
      * to access elements under synchronization.  
      */  
     private final class VectorIterator implements ListIterator<E> {  
         int cursor;              // Index of next element to return;  
         int fence;               // Upper bound on cursor (cache of size())  
         int lastRet;             // Index of last element, or -1 if no such  
         int expectedModCount;    // To check for CME  
   
         VectorIterator(int index, int fence) {  
             this.cursor = index;  
             this.fence = fence;  
             this.lastRet = -1;  
             this.expectedModCount = Vector.this.modCount;  
         }  
1088    
1089          public boolean hasNext() {          public boolean hasNext() {
1090              return cursor < fence;              // Racy but within spec, since modifications are checked
1091          }              // within or after synchronization in next/previous
1092                return cursor != elementCount;
         public boolean hasPrevious() {  
             return cursor > 0;  
         }  
   
         public int nextIndex() {  
             return cursor;  
         }  
   
         public int previousIndex() {  
             return cursor - 1;  
1093          }          }
1094    
1095          public E next() {          public E next() {
1096                synchronized (Vector.this) {
1097                    checkForComodification();
1098              int i = cursor;              int i = cursor;
1099              if (i >= fence)                  if (i >= elementCount)
1100                  throw new NoSuchElementException();                  throw new NoSuchElementException();
             Object next = Vector.this.iteratorGet(i, expectedModCount);  
             lastRet = i;  
1101              cursor = i + 1;              cursor = i + 1;
1102              return (E)next;                  return elementData(lastRet = i);
         }  
   
         public E previous() {  
             int i = cursor - 1;  
             if (i < 0)  
                 throw new NoSuchElementException();  
             Object prev = Vector.this.iteratorGet(i, expectedModCount);  
             lastRet = i;  
             cursor = i;  
             return (E)prev;  
         }  
   
         public void set(E e) {  
             if (lastRet < 0)  
                 throw new IllegalStateException();  
             if (Vector.this.modCount != expectedModCount)  
                 throw new ConcurrentModificationException();  
             try {  
                 Vector.this.set(lastRet, e);  
                 expectedModCount = Vector.this.modCount;  
             } catch (IndexOutOfBoundsException ex) {  
                 throw new ConcurrentModificationException();  
1103              }              }
1104          }          }
1105    
1106          public void remove() {          public void remove() {
1107              int i = lastRet;              if (lastRet == -1)
             if (i < 0)  
1108                  throw new IllegalStateException();                  throw new IllegalStateException();
1109              if (Vector.this.modCount != expectedModCount)              synchronized (Vector.this) {
1110                  throw new ConcurrentModificationException();                  checkForComodification();
1111              try {                  Vector.this.remove(lastRet);
1112                  Vector.this.remove(i);                  expectedModCount = modCount;
                 if (i < cursor)  
                     cursor--;  
                 lastRet = -1;  
                 fence = Vector.this.size();  
                 expectedModCount = Vector.this.modCount;  
             } catch (IndexOutOfBoundsException ex) {  
                 throw new ConcurrentModificationException();  
             }  
1113          }          }
1114                cursor = lastRet;
         public void add(E e) {  
             if (Vector.this.modCount != expectedModCount)  
                 throw new ConcurrentModificationException();  
             try {  
                 int i = cursor;  
                 Vector.this.add(i, e);  
                 cursor = i + 1;  
1115                  lastRet = -1;                  lastRet = -1;
                 fence = Vector.this.size();  
                 expectedModCount = Vector.this.modCount;  
             } catch (IndexOutOfBoundsException ex) {  
                 throw new ConcurrentModificationException();  
             }  
         }  
1116      }      }
1117    
1118      /**          final void checkForComodification() {
1119       * Returns a view of the portion of this List between fromIndex,              if (modCount != expectedModCount)
      * inclusive, and toIndex, exclusive.  (If fromIndex and toIndex are  
      * equal, the returned List is empty.)  The returned List is backed by this  
      * List, so changes in the returned List are reflected in this List, and  
      * vice-versa.  The returned List supports all of the optional List  
      * operations supported by this List.  
      *  
      * <p>This method eliminates the need for explicit range operations (of  
      * the sort that commonly exist for arrays).   Any operation that expects  
      * a List can be used as a range operation by operating on a subList view  
      * instead of a whole List.  For example, the following idiom  
      * removes a range of elements from a List:  
      * <pre>  
      *      list.subList(from, to).clear();  
      * </pre>  
      * Similar idioms may be constructed for indexOf and lastIndexOf,  
      * and all of the algorithms in the Collections class can be applied to  
      * a subList.  
      *  
      * <p>The semantics of the List returned by this method become undefined if  
      * the backing list (i.e., this List) is <i>structurally modified</i> in  
      * any way other than via the returned List.  (Structural modifications are  
      * those that change the size of the List, or otherwise perturb it in such  
      * a fashion that iterations in progress may yield incorrect results.)  
      *  
      * @param fromIndex low endpoint (inclusive) of the subList  
      * @param toIndex high endpoint (exclusive) of the subList  
      * @return a view of the specified range within this List  
      * @throws IndexOutOfBoundsException if an endpoint index value is out of range  
      *         {@code (fromIndex < 0 || toIndex > size)}  
      * @throws IllegalArgumentException if the endpoint indices are out of order  
      *         {@code (fromIndex > toIndex)}  
      */  
     public synchronized List<E> subList(int fromIndex, int toIndex) {  
         return new VectorSubList(this, this, fromIndex, fromIndex, toIndex);  
     }  
   
     /**  
      * This class specializes the AbstractList version of SubList to  
      * avoid the double-indirection penalty that would arise using a  
      * synchronized wrapper, as well as to avoid some unnecessary  
      * checks in sublist iterators.  
      */  
     private static final class VectorSubList<E> extends AbstractList<E> implements RandomAccess {  
         final Vector<E> base;             // base list  
         final AbstractList<E> parent;     // Creating list  
         final int baseOffset;             // index wrt Vector  
         final int parentOffset;           // index wrt parent  
         int length;                       // length of sublist  
   
         VectorSubList(Vector<E> base, AbstractList<E> parent, int baseOffset,  
                      int fromIndex, int toIndex) {  
             if (fromIndex < 0)  
                 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);  
             if (toIndex > parent.size())  
                 throw new IndexOutOfBoundsException("toIndex = " + toIndex);  
             if (fromIndex > toIndex)  
                 throw new IllegalArgumentException("fromIndex(" + fromIndex +  
                                                    ") > toIndex(" + toIndex + ")");  
   
             this.base = base;  
             this.parent = parent;  
             this.baseOffset = baseOffset;  
             this.parentOffset = fromIndex;  
             this.length = toIndex - fromIndex;  
             modCount = base.modCount;  
         }  
   
         /**  
          * Returns an IndexOutOfBoundsException with nicer message  
          */  
         private IndexOutOfBoundsException indexError(int index) {  
             return new IndexOutOfBoundsException("Index: " + index +  
                                                  ", Size: " + length);  
         }  
   
         public E set(int index, E element) {  
             synchronized(base) {  
                 if (index < 0 || index >= length)  
                     throw indexError(index);  
                 if (base.modCount != modCount)  
1120                      throw new ConcurrentModificationException();                      throw new ConcurrentModificationException();
                 return base.set(index + baseOffset, element);  
             }  
         }  
   
         public E get(int index) {  
             synchronized(base) {  
                 if (index < 0 || index >= length)  
                     throw indexError(index);  
                 if (base.modCount != modCount)  
                     throw new ConcurrentModificationException();  
                 return base.get(index + baseOffset);  
             }  
         }  
   
         public int size() {  
             synchronized(base) {  
                 if (base.modCount != modCount)  
                     throw new ConcurrentModificationException();  
                 return length;  
             }  
         }  
   
         public void add(int index, E element) {  
             synchronized(base) {  
                 if (index < 0 || index > length)  
                     throw indexError(index);  
                 if (base.modCount != modCount)  
                     throw new ConcurrentModificationException();  
                 parent.add(index + parentOffset, element);  
                 length++;  
                 modCount = base.modCount;  
             }  
         }  
   
         public E remove(int index) {  
             synchronized(base) {  
                 if (index < 0 || index >= length)  
                     throw indexError(index);  
                 if (base.modCount != modCount)  
                     throw new ConcurrentModificationException();  
                 E result = parent.remove(index + parentOffset);  
                 length--;  
                 modCount = base.modCount;  
                 return result;  
             }  
         }  
   
         protected void removeRange(int fromIndex, int toIndex) {  
             synchronized(base) {  
                 if (base.modCount != modCount)  
                     throw new ConcurrentModificationException();  
                 parent.removeRange(fromIndex + parentOffset,  
                                    toIndex + parentOffset);  
                 length -= (toIndex-fromIndex);  
                 modCount = base.modCount;  
             }  
         }  
   
         public boolean addAll(Collection<? extends E> c) {  
             return addAll(length, c);  
         }  
   
         public boolean addAll(int index, Collection<? extends E> c) {  
             synchronized(base) {  
                 if (index < 0 || index > length)  
                     throw indexError(index);  
                 int cSize = c.size();  
                 if (cSize==0)  
                     return false;  
   
                 if (base.modCount != modCount)  
                     throw new ConcurrentModificationException();  
                 parent.addAll(parentOffset + index, c);  
                 modCount = base.modCount;  
                 length += cSize;  
                 return true;  
             }  
         }  
   
         public boolean equals(Object o) {  
             synchronized(base) {return super.equals(o);}  
         }  
   
         public int hashCode() {  
             synchronized(base) {return super.hashCode();}  
         }  
   
         public int indexOf(Object o) {  
             synchronized(base) {return super.indexOf(o);}  
         }  
   
         public int lastIndexOf(Object o) {  
             synchronized(base) {return super.lastIndexOf(o);}  
         }  
   
         public List<E> subList(int fromIndex, int toIndex) {  
             return new VectorSubList(base, this, fromIndex + baseOffset,  
                                      fromIndex, toIndex);  
         }  
   
         public Iterator<E> iterator() {  
             synchronized(base) {  
                 return new VectorSubListIterator(this, 0);  
             }  
         }  
   
         public synchronized ListIterator<E> listIterator() {  
             synchronized(base) {  
                 return new VectorSubListIterator(this, 0);  
             }  
         }  
   
         public ListIterator<E> listIterator(int index) {  
             synchronized(base) {  
                 if (index < 0 || index > length)  
                     throw indexError(index);  
                 return new VectorSubListIterator(this, index);  
1121              }              }
1122          }          }
1123    
1124          /**          /**
1125           * Same idea as VectorIterator, except routing structural       * An optimized version of AbstractList.ListItr
          * change operations through the sublist.  
1126           */           */
1127          private static final class VectorSubListIterator<E> implements ListIterator<E> {      final class ListItr extends Itr implements ListIterator<E> {
1128              final Vector<E> base;         // base list          ListItr(int index) {
1129              final VectorSubList<E> outer; // Sublist creating this iteraor              super();
1130              final int offset;             // cursor offset wrt base              cursor = index;
             int cursor;                   // Current index  
             int fence;                    // Upper bound on cursor  
             int lastRet;                  // Index of returned element, or -1  
             int expectedModCount;         // Expected modCount of base Vector  
   
             VectorSubListIterator(VectorSubList<E> list, int index) {  
                 this.lastRet = -1;  
                 this.cursor = index;  
                 this.outer = list;  
                 this.offset = list.baseOffset;  
                 this.fence = list.length;  
                 this.base = list.base;  
                 this.expectedModCount = base.modCount;  
             }  
   
             public boolean hasNext() {  
                 return cursor < fence;  
1131              }              }
1132    
1133              public boolean hasPrevious() {              public boolean hasPrevious() {
1134                  return cursor > 0;              return cursor != 0;
1135              }              }
1136    
1137              public int nextIndex() {              public int nextIndex() {
# Line 1392  Line 1142 
1142                  return cursor - 1;                  return cursor - 1;
1143              }              }
1144    
             public E next() {  
                 int i = cursor;  
                 if (cursor >= fence)  
                     throw new NoSuchElementException();  
                 Object next = base.iteratorGet(i + offset, expectedModCount);  
                 lastRet = i;  
                 cursor = i + 1;  
                 return (E)next;  
             }  
   
1145              public E previous() {              public E previous() {
1146                synchronized (Vector.this) {
1147                    checkForComodification();
1148                  int i = cursor - 1;                  int i = cursor - 1;
1149                  if (i < 0)                  if (i < 0)
1150                      throw new NoSuchElementException();                      throw new NoSuchElementException();
                 Object prev = base.iteratorGet(i + offset, expectedModCount);  
                 lastRet = i;  
1151                  cursor = i;                  cursor = i;
1152                  return (E)prev;                  return elementData(lastRet = i);
             }  
   
             public void set(E e) {  
                 if (lastRet < 0)  
                     throw new IllegalStateException();  
                 if (base.modCount != expectedModCount)  
                     throw new ConcurrentModificationException();  
                 try {  
                     outer.set(lastRet, e);  
                     expectedModCount = base.modCount;  
                 } catch (IndexOutOfBoundsException ex) {  
                     throw new ConcurrentModificationException();  
1153                  }                  }
1154              }              }
1155    
1156              public void remove() {          public void set(E e) {
1157                  int i = lastRet;              if (lastRet == -1)
                 if (i < 0)  
1158                      throw new IllegalStateException();                      throw new IllegalStateException();
1159                  if (base.modCount != expectedModCount)              synchronized (Vector.this) {
1160                      throw new ConcurrentModificationException();                  checkForComodification();
1161                  try {                  Vector.this.set(lastRet, e);
                     outer.remove(i);  
                     if (i < cursor)  
                         cursor--;  
                     lastRet = -1;  
                     fence = outer.length;  
                     expectedModCount = base.modCount;  
                 } catch (IndexOutOfBoundsException ex) {  
                     throw new ConcurrentModificationException();  
1162                  }                  }
1163              }              }
1164    
1165              public void add(E e) {              public void add(E e) {
                 if (base.modCount != expectedModCount)  
                     throw new ConcurrentModificationException();  
                 try {  
1166                      int i = cursor;                      int i = cursor;
1167                      outer.add(i, e);              synchronized (Vector.this) {
1168                    checkForComodification();
1169                    Vector.this.add(i, e);
1170                    expectedModCount = modCount;
1171                }
1172                      cursor = i + 1;                      cursor = i + 1;
1173                      lastRet = -1;                      lastRet = -1;
                     fence = outer.length;  
                     expectedModCount = base.modCount;  
                 } catch (IndexOutOfBoundsException ex) {  
                     throw new ConcurrentModificationException();  
                 }  
             }  
1174          }          }
1175      }      }
1176  }  }
   
   
   

Legend:
Removed from v.1.21  
changed lines
  Added in v.1.22

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8