ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/Vector.java
(Generate patch)

Comparing jsr166/src/main/java/util/Vector.java (file contents):
Revision 1.18 by jsr166, Mon Jun 26 00:25:04 2006 UTC vs.
Revision 1.22 by jsr166, Tue Sep 11 15:38:19 2007 UTC

# Line 1 | Line 1
1   /*
2 < * %W% %E%
2 > * Copyright 1994-2007 Sun Microsystems, Inc.  All Rights Reserved.
3 > * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4   *
5 < * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
6 < * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
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;
# Line 23 | Line 41 | package java.util;
41   * capacity of a vector before inserting a large number of
42   * components; this reduces the amount of incremental reallocation.
43   *
44 < * <p>The Iterators returned by Vector's iterator and listIterator
45 < * methods are <em>fail-fast</em>: if the Vector is structurally modified
46 < * at any time after the Iterator is created, in any way except through the
47 < * Iterator's own remove or add methods, the Iterator will throw a
48 < * ConcurrentModificationException.  Thus, in the face of concurrent
49 < * modification, the Iterator fails quickly and cleanly, rather than risking
50 < * arbitrary, non-deterministic behavior at an undetermined time in the future.
51 < * The Enumerations returned by Vector's elements method are <em>not</em>
52 < * fail-fast.
44 > * <p><a name="fail-fast"/>
45 > * The iterators returned by this class's {@link #iterator() iterator} and
46 > * {@link #listIterator(int) listIterator} methods are <em>fail-fast</em>:
47 > * if the vector is structurally modified at any time after the iterator is
48 > * created, in any way except through the iterator's own
49 > * {@link ListIterator#remove() remove} or
50 > * {@link ListIterator#add(Object) add} methods, the iterator will throw a
51 > * {@link ConcurrentModificationException}.  Thus, in the face of
52 > * 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
58   * as it is, generally speaking, impossible to make any hard guarantees in the
# Line 299 | Line 320 | public class Vector<E>
320              public E nextElement() {
321                  synchronized (Vector.this) {
322                      if (count < elementCount) {
323 <                        return (E)elementData[count++];
323 >                        return elementData(count++);
324                      }
325                  }
326                  throw new NoSuchElementException("Vector Enumeration");
# Line 427 | Line 448 | public class Vector<E>
448              throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
449          }
450  
451 <        return (E)elementData[index];
451 >        return elementData(index);
452      }
453  
454      /**
# Line 441 | Line 462 | public class Vector<E>
462          if (elementCount == 0) {
463              throw new NoSuchElementException();
464          }
465 <        return (E)elementData[0];
465 >        return elementData(0);
466      }
467  
468      /**
# Line 455 | Line 476 | public class Vector<E>
476          if (elementCount == 0) {
477              throw new NoSuchElementException();
478          }
479 <        return (E)elementData[elementCount - 1];
479 >        return elementData(elementCount - 1);
480      }
481  
482      /**
# Line 623 | Line 644 | public class Vector<E>
644       */
645      public synchronized Object clone() {
646          try {
647 <            Vector<E> v = (Vector<E>) super.clone();
647 >            @SuppressWarnings("unchecked")
648 >                Vector<E> v = (Vector<E>) super.clone();
649              v.elementData = Arrays.copyOf(elementData, elementCount);
650              v.modCount = 0;
651              return v;
# Line 666 | Line 688 | public class Vector<E>
688       * @throws NullPointerException if the given array is null
689       * @since 1.2
690       */
691 +    @SuppressWarnings("unchecked")
692      public synchronized <T> T[] toArray(T[] a) {
693          if (a.length < elementCount)
694              return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
# Line 680 | Line 703 | public class Vector<E>
703  
704      // 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.
713       *
# Line 693 | Line 721 | public class Vector<E>
721          if (index >= elementCount)
722              throw new ArrayIndexOutOfBoundsException(index);
723  
724 <        return (E)elementData[index];
724 >        return elementData(index);
725      }
726  
727      /**
# Line 711 | Line 739 | public class Vector<E>
739          if (index >= elementCount)
740              throw new ArrayIndexOutOfBoundsException(index);
741  
742 <        Object oldValue = elementData[index];
742 >        E oldValue = elementData(index);
743          elementData[index] = element;
744 <        return (E)oldValue;
744 >        return oldValue;
745      }
746  
747      /**
# Line 775 | Line 803 | public class Vector<E>
803          modCount++;
804          if (index >= elementCount)
805              throw new ArrayIndexOutOfBoundsException(index);
806 <        Object oldValue = elementData[index];
806 >        E oldValue = elementData(index);
807  
808          int numMoved = elementCount - index - 1;
809          if (numMoved > 0)
# Line 783 | Line 811 | public class Vector<E>
811                               numMoved);
812          elementData[--elementCount] = null; // Let gc do its work
813  
814 <        return (E)oldValue;
814 >        return oldValue;
815      }
816  
817      /**
# Line 941 | Line 969 | public class Vector<E>
969      }
970  
971      /**
972 <     * Removes from this List all of the elements whose index is between
973 <     * fromIndex, inclusive and toIndex, exclusive.  Shifts any succeeding
974 <     * elements to the left (reduces their index).
975 <     * This call shortens the Vector by (toIndex - fromIndex) elements.  (If
976 <     * toIndex==fromIndex, this operation has no effect.)
972 >     * Returns a view of the portion of this List between fromIndex,
973 >     * inclusive, and toIndex, exclusive.  (If fromIndex and toIndex are
974 >     * equal, the returned List is empty.)  The returned List is backed by this
975 >     * List, so changes in the returned List are reflected in this List, and
976 >     * 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
998 <     * @param toIndex index after last element to be removed
997 >     * @param fromIndex low endpoint (inclusive) of the subList
998 >     * @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) {
1018          modCount++;
# Line 974 | Line 1038 | public class Vector<E>
1038      }
1039  
1040      /**
1041 <     * Returns a list-iterator of the elements in this list (in proper
1041 >     * Returns a list iterator over the elements in this list (in proper
1042       * sequence), starting at the specified position in the list.
1043 <     * Obeys the general contract of {@link List#listIterator(int)}.
1043 >     * 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 returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
1049       *
981     * <p>The list-iterator is <i>fail-fast</i>: if the list is structurally
982     * modified at any time after the Iterator is created, in any way except
983     * through the list-iterator's own {@code remove} or {@code add}
984     * methods, the list-iterator will throw a
985     * {@code ConcurrentModificationException}.  Thus, in the face of
986     * concurrent modification, the iterator fails quickly and cleanly, rather
987     * than risking arbitrary, non-deterministic behavior at an undetermined
988     * time in the future.
989     *
990     * @param index index of the first element to be returned from the
991     *        list-iterator (by a call to {@link ListIterator#next})
992     * @return a list-iterator of the elements in this list (in proper
993     *         sequence), starting at the specified position in the list
1050       * @throws IndexOutOfBoundsException {@inheritDoc}
1051       */
1052      public synchronized ListIterator<E> listIterator(int index) {
1053          if (index < 0 || index > elementCount)
1054              throw new IndexOutOfBoundsException("Index: "+index);
1055 <        return new VectorIterator(index, elementCount);
1055 >        return new ListItr(index);
1056      }
1057  
1058      /**
1059 <     * {@inheritDoc}
1059 >     * 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() {
1067 <        return new VectorIterator(0, elementCount);
1067 >        return new ListItr(0);
1068      }
1069  
1070      /**
1071       * 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
1076       */
1077      public synchronized Iterator<E> iterator() {
1078 <        return new VectorIterator(0, elementCount);
1078 >        return new Itr();
1079      }
1080  
1081      /**
1082 <     * Helper method to access array elements under synchronization by
1020 <     * iterators. The caller performs index check with respect to
1021 <     * expected bounds, so errors accessing the element are reported
1022 <     * as ConcurrentModificationExceptions.
1082 >     * An optimized version of AbstractList.Itr
1083       */
1084 <    final synchronized Object iteratorGet(int index, int expectedModCount) {
1085 <        if (modCount == expectedModCount) {
1086 <            try {
1087 <                return elementData[index];
1088 <            } catch(IndexOutOfBoundsException fallThrough) {
1084 >    private class Itr implements Iterator<E> {
1085 >        int cursor;       // index of next element to return
1086 >        int lastRet = -1; // index of last element returned; -1 if no such
1087 >        int expectedModCount = modCount;
1088 >
1089 >        public boolean hasNext() {
1090 >            // Racy but within spec, since modifications are checked
1091 >            // within or after synchronization in next/previous
1092 >            return cursor != elementCount;
1093 >        }
1094 >
1095 >        public E next() {
1096 >            synchronized (Vector.this) {
1097 >                checkForComodification();
1098 >                int i = cursor;
1099 >                if (i >= elementCount)
1100 >                    throw new NoSuchElementException();
1101 >                cursor = i + 1;
1102 >                return elementData(lastRet = i);
1103 >            }
1104 >        }
1105 >
1106 >        public void remove() {
1107 >            if (lastRet == -1)
1108 >                throw new IllegalStateException();
1109 >            synchronized (Vector.this) {
1110 >                checkForComodification();
1111 >                Vector.this.remove(lastRet);
1112 >                expectedModCount = modCount;
1113              }
1114 <        }
1115 <        throw new ConcurrentModificationException();
1114 >            cursor = lastRet;
1115 >            lastRet = -1;
1116 >        }
1117 >
1118 >        final void checkForComodification() {
1119 >            if (modCount != expectedModCount)
1120 >                throw new ConcurrentModificationException();
1121 >        }
1122      }
1123  
1124      /**
1125 <     * Streamlined specialization of AbstractList version of iterator.
1036 <     * Locally perfroms bounds checks, but relies on outer Vector
1037 <     * to access elements under synchronization.
1125 >     * An optimized version of AbstractList.ListItr
1126       */
1127 <    private final class VectorIterator implements ListIterator<E> {
1128 <        int cursor;              // Index of next element to return;
1129 <        int fence;               // Upper bound on cursor (cache of size())
1130 <        int lastRet;             // Index of last element, or -1 if no such
1043 <        int expectedModCount;    // To check for CME
1044 <
1045 <        VectorIterator(int index, int fence) {
1046 <            this.cursor = index;
1047 <            this.fence = fence;
1048 <            this.lastRet = -1;
1049 <            this.expectedModCount = Vector.this.modCount;
1050 <        }
1051 <
1052 <        public boolean hasNext() {
1053 <            return cursor < fence;
1127 >    final class ListItr extends Itr implements ListIterator<E> {
1128 >        ListItr(int index) {
1129 >            super();
1130 >            cursor = index;
1131          }
1132  
1133          public boolean hasPrevious() {
1134 <            return cursor > 0;
1134 >            return cursor != 0;
1135          }
1136  
1137          public int nextIndex() {
# Line 1065 | Line 1142 | public class Vector<E>
1142              return cursor - 1;
1143          }
1144  
1145 <        public E next() {
1146 <            int i = cursor;
1147 <            if (i >= fence)
1148 <                throw new NoSuchElementException();
1149 <            Object next = Vector.this.iteratorGet(i, expectedModCount);
1150 <            lastRet = i;
1151 <            cursor = i + 1;
1152 <            return (E)next;
1153 <        }
1077 <
1078 <        public E previous() {
1079 <            int i = cursor - 1;
1080 <            if (i < 0)
1081 <                throw new NoSuchElementException();
1082 <            Object prev = Vector.this.iteratorGet(i, expectedModCount);
1083 <            lastRet = i;
1084 <            cursor = i;
1085 <            return (E)prev;
1145 >        public E previous() {
1146 >            synchronized (Vector.this) {
1147 >                checkForComodification();
1148 >                int i = cursor - 1;
1149 >                if (i < 0)
1150 >                    throw new NoSuchElementException();
1151 >                cursor = i;
1152 >                return elementData(lastRet = i);
1153 >            }
1154          }
1155  
1156          public void set(E e) {
1157 <            if (lastRet < 0)
1157 >            if (lastRet == -1)
1158                  throw new IllegalStateException();
1159 <            if (Vector.this.modCount != expectedModCount)
1160 <                throw new ConcurrentModificationException();
1161 <            try {
1094 <                Vector.this.set(lastRet, e);
1095 <                expectedModCount = Vector.this.modCount;
1096 <            } catch (IndexOutOfBoundsException ex) {
1097 <                throw new ConcurrentModificationException();
1098 <            }
1099 <        }
1100 <
1101 <        public void remove() {
1102 <            int i = lastRet;
1103 <            if (i < 0)
1104 <                throw new IllegalStateException();
1105 <            if (Vector.this.modCount != expectedModCount)
1106 <                throw new ConcurrentModificationException();
1107 <            try {
1108 <                Vector.this.remove(i);
1109 <                if (i < cursor)
1110 <                    cursor--;
1111 <                lastRet = -1;
1112 <                fence = Vector.this.size();
1113 <                expectedModCount = Vector.this.modCount;
1114 <            } catch (IndexOutOfBoundsException ex) {
1115 <                throw new ConcurrentModificationException();
1159 >            synchronized (Vector.this) {
1160 >                checkForComodification();
1161 >                Vector.this.set(lastRet, e);
1162              }
1163          }
1164  
1165          public void add(E e) {
1166 <            if (Vector.this.modCount != expectedModCount)
1167 <                throw new ConcurrentModificationException();
1168 <            try {
1169 <                int i = cursor;
1170 <                Vector.this.add(i, e);
1125 <                cursor = i + 1;
1126 <                lastRet = -1;
1127 <                fence = Vector.this.size();
1128 <                expectedModCount = Vector.this.modCount;
1129 <            } catch (IndexOutOfBoundsException ex) {
1130 <                throw new ConcurrentModificationException();
1166 >            int i = cursor;
1167 >            synchronized (Vector.this) {
1168 >                checkForComodification();
1169 >                Vector.this.add(i, e);
1170 >                expectedModCount = modCount;
1171              }
1172 +            cursor = i + 1;
1173 +            lastRet = -1;
1174          }
1175      }
1134
1135    /**
1136     * Returns a view of the portion of this List between fromIndex,
1137     * inclusive, and toIndex, exclusive.  (If fromIndex and toIndex are
1138     * equal, the returned List is empty.)  The returned List is backed by this
1139     * List, so changes in the returned List are reflected in this List, and
1140     * vice-versa.  The returned List supports all of the optional List
1141     * operations supported by this List.
1142     *
1143     * <p>This method eliminates the need for explicit range operations (of
1144     * the sort that commonly exist for arrays).   Any operation that expects
1145     * a List can be used as a range operation by operating on a subList view
1146     * instead of a whole List.  For example, the following idiom
1147     * removes a range of elements from a List:
1148     * <pre>
1149     *      list.subList(from, to).clear();
1150     * </pre>
1151     * Similar idioms may be constructed for indexOf and lastIndexOf,
1152     * and all of the algorithms in the Collections class can be applied to
1153     * a subList.
1154     *
1155     * <p>The semantics of the List returned by this method become undefined if
1156     * the backing list (i.e., this List) is <i>structurally modified</i> in
1157     * any way other than via the returned List.  (Structural modifications are
1158     * those that change the size of the List, or otherwise perturb it in such
1159     * a fashion that iterations in progress may yield incorrect results.)
1160     *
1161     * @param fromIndex low endpoint (inclusive) of the subList
1162     * @param toIndex high endpoint (exclusive) of the subList
1163     * @return a view of the specified range within this List
1164     * @throws IndexOutOfBoundsException if an endpoint index value is out of range
1165     *         {@code (fromIndex < 0 || toIndex > size)}
1166     * @throws IllegalArgumentException if the endpoint indices are out of order
1167     *         {@code (fromIndex > toIndex)}
1168     */
1169    public synchronized List<E> subList(int fromIndex, int toIndex) {
1170        return new VectorSubList(this, this, fromIndex, fromIndex, toIndex);
1171    }
1172
1173    /**
1174     * This class specializes the AbstractList version of SubList to
1175     * avoid the double-indirection penalty that would arise using a
1176     * synchronized wrapper, as well as to avoid some unnecessary
1177     * checks in sublist iterators.
1178     */
1179    private static final class VectorSubList<E> extends AbstractList<E> implements RandomAccess {
1180        final Vector<E> base;             // base list
1181        final AbstractList<E> parent;     // Creating list
1182        final int baseOffset;             // index wrt Vector
1183        final int parentOffset;           // index wrt parent
1184        int length;                       // length of sublist
1185
1186        VectorSubList(Vector<E> base, AbstractList<E> parent, int baseOffset,
1187                     int fromIndex, int toIndex) {
1188            if (fromIndex < 0)
1189                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
1190            if (toIndex > parent.size())
1191                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
1192            if (fromIndex > toIndex)
1193                throw new IllegalArgumentException("fromIndex(" + fromIndex +
1194                                                   ") > toIndex(" + toIndex + ")");
1195
1196            this.base = base;
1197            this.parent = parent;
1198            this.baseOffset = baseOffset;
1199            this.parentOffset = fromIndex;
1200            this.length = toIndex - fromIndex;
1201            modCount = base.modCount;
1202        }
1203
1204        /**
1205         * Returns an IndexOutOfBoundsException with nicer message
1206         */
1207        private IndexOutOfBoundsException indexError(int index) {
1208            return new IndexOutOfBoundsException("Index: " + index +
1209                                                 ", Size: " + length);
1210        }
1211
1212        public E set(int index, E element) {
1213            synchronized(base) {
1214                if (index < 0 || index >= length)
1215                    throw indexError(index);
1216                if (base.modCount != modCount)
1217                    throw new ConcurrentModificationException();
1218                return base.set(index + baseOffset, element);
1219            }
1220        }
1221
1222        public E get(int index) {
1223            synchronized(base) {
1224                if (index < 0 || index >= length)
1225                    throw indexError(index);
1226                if (base.modCount != modCount)
1227                    throw new ConcurrentModificationException();
1228                return base.get(index + baseOffset);
1229            }
1230        }
1231
1232        public int size() {
1233            synchronized(base) {
1234                if (base.modCount != modCount)
1235                    throw new ConcurrentModificationException();
1236                return length;
1237            }
1238        }
1239
1240        public void add(int index, E element) {
1241            synchronized(base) {
1242                if (index < 0 || index > length)
1243                    throw indexError(index);
1244                if (base.modCount != modCount)
1245                    throw new ConcurrentModificationException();
1246                parent.add(index + parentOffset, element);
1247                length++;
1248                modCount = base.modCount;
1249            }
1250        }
1251
1252        public E remove(int index) {
1253            synchronized(base) {
1254                if (index < 0 || index >= length)
1255                    throw indexError(index);
1256                if (base.modCount != modCount)
1257                    throw new ConcurrentModificationException();
1258                E result = parent.remove(index + parentOffset);
1259                length--;
1260                modCount = base.modCount;
1261                return result;
1262            }
1263        }
1264
1265        protected void removeRange(int fromIndex, int toIndex) {
1266            synchronized(base) {
1267                if (base.modCount != modCount)
1268                    throw new ConcurrentModificationException();
1269                parent.removeRange(fromIndex + parentOffset,
1270                                   toIndex + parentOffset);
1271                length -= (toIndex-fromIndex);
1272                modCount = base.modCount;
1273            }
1274        }
1275
1276        public boolean addAll(Collection<? extends E> c) {
1277            return addAll(length, c);
1278        }
1279
1280        public boolean addAll(int index, Collection<? extends E> c) {
1281            synchronized(base) {
1282                if (index < 0 || index > length)
1283                    throw indexError(index);
1284                int cSize = c.size();
1285                if (cSize==0)
1286                    return false;
1287
1288                if (base.modCount != modCount)
1289                    throw new ConcurrentModificationException();
1290                parent.addAll(parentOffset + index, c);
1291                modCount = base.modCount;
1292                length += cSize;
1293                return true;
1294            }
1295        }
1296
1297        public boolean equals(Object o) {
1298            synchronized(base) {return super.equals(o);}
1299        }
1300
1301        public int hashCode() {
1302            synchronized(base) {return super.hashCode();}
1303        }
1304
1305        public int indexOf(Object o) {
1306            synchronized(base) {return super.indexOf(o);}
1307        }
1308
1309        public int lastIndexOf(Object o) {
1310            synchronized(base) {return super.lastIndexOf(o);}
1311        }
1312
1313        public List<E> subList(int fromIndex, int toIndex) {
1314            return new VectorSubList(base, this, fromIndex + baseOffset,
1315                                     fromIndex, toIndex);
1316        }
1317
1318        public Iterator<E> iterator() {
1319            synchronized(base) {
1320                return new VectorSubListIterator(this, 0);
1321            }
1322        }
1323
1324        public synchronized ListIterator<E> listIterator() {
1325            synchronized(base) {
1326                return new VectorSubListIterator(this, 0);
1327            }
1328        }
1329
1330        public ListIterator<E> listIterator(int index) {
1331            synchronized(base) {
1332                if (index < 0 || index > length)
1333                    throw indexError(index);
1334                return new VectorSubListIterator(this, index);
1335            }
1336        }
1337
1338        /**
1339         * Same idea as VectorIterator, except routing structural
1340         * change operations through the sublist.
1341         */
1342        private static final class VectorSubListIterator<E> implements ListIterator<E> {
1343            final Vector<E> base;         // base list
1344            final VectorSubList<E> outer; // Sublist creating this iteraor
1345            final int offset;             // cursor offset wrt base
1346            int cursor;                   // Current index
1347            int fence;                    // Upper bound on cursor
1348            int lastRet;                  // Index of returned element, or -1
1349            int expectedModCount;         // Expected modCount of base Vector
1350
1351            VectorSubListIterator(VectorSubList<E> list, int index) {
1352                this.lastRet = -1;
1353                this.cursor = index;
1354                this.outer = list;
1355                this.offset = list.baseOffset;
1356                this.fence = list.length;
1357                this.base = list.base;
1358                this.expectedModCount = base.modCount;
1359            }
1360
1361            public boolean hasNext() {
1362                return cursor < fence;
1363            }
1364
1365            public boolean hasPrevious() {
1366                return cursor > 0;
1367            }
1368
1369            public int nextIndex() {
1370                return cursor;
1371            }
1372
1373            public int previousIndex() {
1374                return cursor - 1;
1375            }
1376
1377            public E next() {
1378                int i = cursor;
1379                if (cursor >= fence)
1380                    throw new NoSuchElementException();
1381                Object next = base.iteratorGet(i + offset, expectedModCount);
1382                lastRet = i;
1383                cursor = i + 1;
1384                return (E)next;
1385            }
1386
1387            public E previous() {
1388                int i = cursor - 1;
1389                if (i < 0)
1390                    throw new NoSuchElementException();
1391                Object prev = base.iteratorGet(i + offset, expectedModCount);
1392                lastRet = i;
1393                cursor = i;
1394                return (E)prev;
1395            }
1396
1397            public void set(E e) {
1398                if (lastRet < 0)
1399                    throw new IllegalStateException();
1400                if (base.modCount != expectedModCount)
1401                    throw new ConcurrentModificationException();
1402                try {
1403                    outer.set(lastRet, e);
1404                    expectedModCount = base.modCount;
1405                } catch (IndexOutOfBoundsException ex) {
1406                    throw new ConcurrentModificationException();
1407                }
1408            }
1409
1410            public void remove() {
1411                int i = lastRet;
1412                if (i < 0)
1413                    throw new IllegalStateException();
1414                if (base.modCount != expectedModCount)
1415                    throw new ConcurrentModificationException();
1416                try {
1417                    outer.remove(i);
1418                    if (i < cursor)
1419                        cursor--;
1420                    lastRet = -1;
1421                    fence = outer.length;
1422                    expectedModCount = base.modCount;
1423                } catch (IndexOutOfBoundsException ex) {
1424                    throw new ConcurrentModificationException();
1425                }
1426            }
1427
1428            public void add(E e) {
1429                if (base.modCount != expectedModCount)
1430                    throw new ConcurrentModificationException();
1431                try {
1432                    int i = cursor;
1433                    outer.add(i, e);
1434                    cursor = i + 1;
1435                    lastRet = -1;
1436                    fence = outer.length;
1437                    expectedModCount = base.modCount;
1438                } catch (IndexOutOfBoundsException ex) {
1439                    throw new ConcurrentModificationException();
1440                }
1441            }
1442        }
1443    }
1176   }
1445
1446
1447

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines