655 */
656 private void rangeCheck(int index) {
657 if (index >= size)
658 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
659 }
660
661 /**
662 * A version of rangeCheck used by add and addAll.
663 */
664 private void rangeCheckForAdd(int index) {
665 if (index > size || index < 0)
666 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
667 }
668
669 /**
670 * Constructs an IndexOutOfBoundsException detail message.
671 * Of the many possible refactorings of the error handling code,
672 * this "outlining" performs best with both server and client VMs.
673 */
674 private String outOfBoundsMsg(int index) {
675 return "Index: "+index+", Size: "+size;
676 }
677
678 /**
679 * A version used in checking (fromIndex > toIndex) condition
680 */
681 private static String outOfBoundsMsg(int fromIndex, int toIndex) {
682 return "From Index: " + fromIndex + " > To Index: " + toIndex;
683 }
684
685 /**
686 * Removes from this list all of its elements that are contained in the
687 * specified collection.
688 *
689 * @param c collection containing elements to be removed from this list
690 * @return {@code true} if this list changed as a result of the call
691 * @throws ClassCastException if the class of an element of this list
692 * is incompatible with the specified collection
693 * (<a href="Collection.html#optional-restrictions">optional</a>)
694 * @throws NullPointerException if this list contains a null element and the
695 * specified collection does not permit null elements
989 * instead of a whole list. For example, the following idiom
990 * removes a range of elements from a list:
991 * <pre>
992 * list.subList(from, to).clear();
993 * </pre>
994 * Similar idioms may be constructed for {@link #indexOf(Object)} and
995 * {@link #lastIndexOf(Object)}, and all of the algorithms in the
996 * {@link Collections} class can be applied to a subList.
997 *
998 * <p>The semantics of the list returned by this method become undefined if
999 * the backing list (i.e., this list) is <i>structurally modified</i> in
1000 * any way other than via the returned list. (Structural modifications are
1001 * those that change the size of this list, or otherwise perturb it in such
1002 * a fashion that iterations in progress may yield incorrect results.)
1003 *
1004 * @throws IndexOutOfBoundsException {@inheritDoc}
1005 * @throws IllegalArgumentException {@inheritDoc}
1006 */
1007 public List<E> subList(int fromIndex, int toIndex) {
1008 subListRangeCheck(fromIndex, toIndex, size);
1009 return new SubList(this, 0, fromIndex, toIndex);
1010 }
1011
1012 static void subListRangeCheck(int fromIndex, int toIndex, int size) {
1013 if (fromIndex < 0)
1014 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
1015 if (toIndex > size)
1016 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
1017 if (fromIndex > toIndex)
1018 throw new IllegalArgumentException("fromIndex(" + fromIndex +
1019 ") > toIndex(" + toIndex + ")");
1020 }
1021
1022 private class SubList extends AbstractList<E> implements RandomAccess {
1023 private final AbstractList<E> parent;
1024 private final int parentOffset;
1025 private final int offset;
1026 int size;
1027
1028 SubList(AbstractList<E> parent,
1029 int offset, int fromIndex, int toIndex) {
1030 this.parent = parent;
1031 this.parentOffset = fromIndex;
1032 this.offset = offset + fromIndex;
1033 this.size = toIndex - fromIndex;
1034 this.modCount = ArrayList.this.modCount;
1035 }
1036
1037 public E set(int index, E e) {
1038 rangeCheck(index);
1039 checkForComodification();
1040 E oldValue = ArrayList.this.elementData(offset + index);
1041 ArrayList.this.elementData[offset + index] = e;
1042 return oldValue;
1043 }
1044
1045 public E get(int index) {
1046 rangeCheck(index);
1047 checkForComodification();
1048 return ArrayList.this.elementData(offset + index);
1049 }
1050
1051 public int size() {
1052 checkForComodification();
1053 return this.size;
1054 }
1055
1056 public void add(int index, E e) {
1057 rangeCheckForAdd(index);
1058 checkForComodification();
1059 parent.add(parentOffset + index, e);
1060 this.modCount = parent.modCount;
1061 this.size++;
1062 }
1063
1064 public E remove(int index) {
1065 rangeCheck(index);
1066 checkForComodification();
1067 E result = parent.remove(parentOffset + index);
1068 this.modCount = parent.modCount;
1069 this.size--;
1070 return result;
1071 }
1072
1073 protected void removeRange(int fromIndex, int toIndex) {
1074 checkForComodification();
1075 parent.removeRange(parentOffset + fromIndex,
1076 parentOffset + toIndex);
1077 this.modCount = parent.modCount;
1078 this.size -= toIndex - fromIndex;
1079 }
1080
1081 public boolean addAll(Collection<? extends E> c) {
1082 return addAll(this.size, c);
1083 }
1084
1085 public boolean addAll(int index, Collection<? extends E> c) {
1086 rangeCheckForAdd(index);
1087 int cSize = c.size();
1088 if (cSize==0)
1089 return false;
1090
1091 checkForComodification();
1092 parent.addAll(parentOffset + index, c);
1093 this.modCount = parent.modCount;
1094 this.size += cSize;
1095 return true;
1096 }
1097
1098 public Iterator<E> iterator() {
1099 return listIterator();
1100 }
1101
1102 public ListIterator<E> listIterator(final int index) {
1103 checkForComodification();
1104 rangeCheckForAdd(index);
1105 final int offset = this.offset;
1106
1107 return new ListIterator<E>() {
1108 int cursor = index;
1109 int lastRet = -1;
1110 int expectedModCount = ArrayList.this.modCount;
1111
1112 public boolean hasNext() {
1113 return cursor != SubList.this.size;
1114 }
1115
1116 @SuppressWarnings("unchecked")
1117 public E next() {
1118 checkForComodification();
1119 int i = cursor;
1120 if (i >= SubList.this.size)
1121 throw new NoSuchElementException();
1122 Object[] elementData = ArrayList.this.elementData;
1123 if (offset + i >= elementData.length)
1124 throw new ConcurrentModificationException();
1125 cursor = i + 1;
1126 return (E) elementData[offset + (lastRet = i)];
1127 }
1128
1129 public boolean hasPrevious() {
1130 return cursor != 0;
1131 }
1132
1133 @SuppressWarnings("unchecked")
1134 public E previous() {
1135 checkForComodification();
1136 int i = cursor - 1;
1137 if (i < 0)
1138 throw new NoSuchElementException();
1139 Object[] elementData = ArrayList.this.elementData;
1140 if (offset + i >= elementData.length)
1141 throw new ConcurrentModificationException();
1142 cursor = i;
1143 return (E) elementData[offset + (lastRet = i)];
1144 }
1145
1146 @SuppressWarnings("unchecked")
1147 public void forEachRemaining(Consumer<? super E> consumer) {
1148 Objects.requireNonNull(consumer);
1149 final int size = SubList.this.size;
1150 int i = cursor;
1151 if (i >= size) {
1152 return;
1153 }
1154 final Object[] elementData = ArrayList.this.elementData;
1155 if (offset + i >= elementData.length) {
1156 throw new ConcurrentModificationException();
1157 }
1158 while (i != size && modCount == expectedModCount) {
1159 consumer.accept((E) elementData[offset + (i++)]);
1160 }
1161 // update once at end of iteration to reduce heap write traffic
1162 lastRet = cursor = i;
1163 checkForComodification();
1164 }
1165
1166 public int nextIndex() {
1167 return cursor;
1168 }
1169
1170 public int previousIndex() {
1171 return cursor - 1;
1172 }
1173
1174 public void remove() {
1175 if (lastRet < 0)
1176 throw new IllegalStateException();
1177 checkForComodification();
1178
1179 try {
1180 SubList.this.remove(lastRet);
1181 cursor = lastRet;
1182 lastRet = -1;
1183 expectedModCount = ArrayList.this.modCount;
1184 } catch (IndexOutOfBoundsException ex) {
1185 throw new ConcurrentModificationException();
1186 }
1187 }
1188
1189 public void set(E e) {
1190 if (lastRet < 0)
1191 throw new IllegalStateException();
1192 checkForComodification();
1193
1194 try {
1195 ArrayList.this.set(offset + lastRet, e);
1196 } catch (IndexOutOfBoundsException ex) {
1197 throw new ConcurrentModificationException();
1198 }
1199 }
1200
1201 public void add(E e) {
1202 checkForComodification();
1203
1204 try {
1205 int i = cursor;
1206 SubList.this.add(i, e);
1207 cursor = i + 1;
1208 lastRet = -1;
1209 expectedModCount = ArrayList.this.modCount;
1210 } catch (IndexOutOfBoundsException ex) {
1211 throw new ConcurrentModificationException();
1212 }
1213 }
1214
1215 final void checkForComodification() {
1216 if (expectedModCount != ArrayList.this.modCount)
1217 throw new ConcurrentModificationException();
1218 }
1219 };
1220 }
1221
1222 public List<E> subList(int fromIndex, int toIndex) {
1223 subListRangeCheck(fromIndex, toIndex, size);
1224 return new SubList(this, offset, fromIndex, toIndex);
1225 }
1226
1227 private void rangeCheck(int index) {
1228 if (index < 0 || index >= this.size)
1229 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1230 }
1231
1232 private void rangeCheckForAdd(int index) {
1233 if (index < 0 || index > this.size)
1234 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1235 }
1236
1237 private String outOfBoundsMsg(int index) {
1238 return "Index: "+index+", Size: "+this.size;
1239 }
1240
1241 private void checkForComodification() {
1242 if (ArrayList.this.modCount != this.modCount)
1243 throw new ConcurrentModificationException();
1244 }
1245
1246 public Spliterator<E> spliterator() {
1247 checkForComodification();
1248 return new ArrayListSpliterator<>(ArrayList.this, offset,
1249 offset + this.size, this.modCount);
1250 }
1251 }
1252
1253 @Override
1254 public void forEach(Consumer<? super E> action) {
1255 Objects.requireNonNull(action);
1256 final int expectedModCount = modCount;
1257 @SuppressWarnings("unchecked")
1258 final E[] elementData = (E[]) this.elementData;
1259 final int size = this.size;
1260 for (int i=0; modCount == expectedModCount && i < size; i++) {
1261 action.accept(elementData[i]);
1262 }
1263 if (modCount != expectedModCount) {
1264 throw new ConcurrentModificationException();
1265 }
1266 }
1267
1268 /**
1269 * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
1270 * and <em>fail-fast</em> {@link Spliterator} over the elements in this
1453 for (int i=0; modCount == expectedModCount && i < size; i++) {
1454 elementData[i] = operator.apply((E) elementData[i]);
1455 }
1456 if (modCount != expectedModCount) {
1457 throw new ConcurrentModificationException();
1458 }
1459 modCount++;
1460 }
1461
1462 @Override
1463 @SuppressWarnings("unchecked")
1464 public void sort(Comparator<? super E> c) {
1465 final int expectedModCount = modCount;
1466 Arrays.sort((E[]) elementData, 0, size, c);
1467 if (modCount != expectedModCount) {
1468 throw new ConcurrentModificationException();
1469 }
1470 modCount++;
1471 }
1472 }
|
655 */
656 private void rangeCheck(int index) {
657 if (index >= size)
658 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
659 }
660
661 /**
662 * A version of rangeCheck used by add and addAll.
663 */
664 private void rangeCheckForAdd(int index) {
665 if (index > size || index < 0)
666 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
667 }
668
669 /**
670 * Constructs an IndexOutOfBoundsException detail message.
671 * Of the many possible refactorings of the error handling code,
672 * this "outlining" performs best with both server and client VMs.
673 */
674 private String outOfBoundsMsg(int index) {
675 return "Index: " + index + ", Size: " + size;
676 }
677
678 /**
679 * A version used in checking (fromIndex > toIndex) condition
680 */
681 private static String outOfBoundsMsg(int fromIndex, int toIndex) {
682 return "From Index: " + fromIndex + " > To Index: " + toIndex;
683 }
684
685 /**
686 * Removes from this list all of its elements that are contained in the
687 * specified collection.
688 *
689 * @param c collection containing elements to be removed from this list
690 * @return {@code true} if this list changed as a result of the call
691 * @throws ClassCastException if the class of an element of this list
692 * is incompatible with the specified collection
693 * (<a href="Collection.html#optional-restrictions">optional</a>)
694 * @throws NullPointerException if this list contains a null element and the
695 * specified collection does not permit null elements
989 * instead of a whole list. For example, the following idiom
990 * removes a range of elements from a list:
991 * <pre>
992 * list.subList(from, to).clear();
993 * </pre>
994 * Similar idioms may be constructed for {@link #indexOf(Object)} and
995 * {@link #lastIndexOf(Object)}, and all of the algorithms in the
996 * {@link Collections} class can be applied to a subList.
997 *
998 * <p>The semantics of the list returned by this method become undefined if
999 * the backing list (i.e., this list) is <i>structurally modified</i> in
1000 * any way other than via the returned list. (Structural modifications are
1001 * those that change the size of this list, or otherwise perturb it in such
1002 * a fashion that iterations in progress may yield incorrect results.)
1003 *
1004 * @throws IndexOutOfBoundsException {@inheritDoc}
1005 * @throws IllegalArgumentException {@inheritDoc}
1006 */
1007 public List<E> subList(int fromIndex, int toIndex) {
1008 subListRangeCheck(fromIndex, toIndex, size);
1009 return new ArraySubList<>(this, fromIndex, toIndex);
1010 }
1011
1012 @Override
1013 public void forEach(Consumer<? super E> action) {
1014 Objects.requireNonNull(action);
1015 final int expectedModCount = modCount;
1016 @SuppressWarnings("unchecked")
1017 final E[] elementData = (E[]) this.elementData;
1018 final int size = this.size;
1019 for (int i=0; modCount == expectedModCount && i < size; i++) {
1020 action.accept(elementData[i]);
1021 }
1022 if (modCount != expectedModCount) {
1023 throw new ConcurrentModificationException();
1024 }
1025 }
1026
1027 /**
1028 * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
1029 * and <em>fail-fast</em> {@link Spliterator} over the elements in this
1212 for (int i=0; modCount == expectedModCount && i < size; i++) {
1213 elementData[i] = operator.apply((E) elementData[i]);
1214 }
1215 if (modCount != expectedModCount) {
1216 throw new ConcurrentModificationException();
1217 }
1218 modCount++;
1219 }
1220
1221 @Override
1222 @SuppressWarnings("unchecked")
1223 public void sort(Comparator<? super E> c) {
1224 final int expectedModCount = modCount;
1225 Arrays.sort((E[]) elementData, 0, size, c);
1226 if (modCount != expectedModCount) {
1227 throw new ConcurrentModificationException();
1228 }
1229 modCount++;
1230 }
1231 }
1232
1233 class ArraySubList<E> extends AbstractList<E> implements RandomAccess {
1234 final ArrayList<E> root;
1235 final ArraySubList<E> parent;
1236 final int offset;
1237 int size;
1238
1239 /**
1240 * Constructs a sublist of an arbitrary ArrayList.
1241 */
1242 public ArraySubList(ArrayList<E> root, int fromIndex, int toIndex) {
1243 this.root = root;
1244 this.parent = null;
1245 this.offset = fromIndex;
1246 this.size = toIndex - fromIndex;
1247 this.modCount = root.modCount;
1248 }
1249
1250 /**
1251 * Constructs a sublist of another ArraySubList.
1252 */
1253 private ArraySubList(ArraySubList<E> parent, int fromIndex, int toIndex) {
1254 this.root = parent.root;
1255 this.parent = parent;
1256 this.offset = parent.offset + fromIndex;
1257 this.size = toIndex - fromIndex;
1258 this.modCount = root.modCount;
1259 }
1260
1261 public E set(int index, E element) {
1262 rangeCheck(index);
1263 checkForComodification();
1264 E oldValue = root.elementData(offset + index);
1265 root.elementData[offset + index] = element;
1266 return oldValue;
1267 }
1268
1269 public E get(int index) {
1270 rangeCheck(index);
1271 checkForComodification();
1272 return root.elementData(offset + index);
1273 }
1274
1275 public int size() {
1276 checkForComodification();
1277 return size;
1278 }
1279
1280 public void add(int index, E element) {
1281 rangeCheckForAdd(index);
1282 checkForComodification();
1283 root.add(offset + index, element);
1284 updateSizeAndModCount(1);
1285 }
1286
1287 public E remove(int index) {
1288 rangeCheck(index);
1289 checkForComodification();
1290 E result = root.remove(offset + index);
1291 updateSizeAndModCount(-1);
1292 return result;
1293 }
1294
1295 protected void removeRange(int fromIndex, int toIndex) {
1296 checkForComodification();
1297 root.removeRange(offset + fromIndex, offset + toIndex);
1298 updateSizeAndModCount(fromIndex - toIndex);
1299 }
1300
1301 public boolean addAll(Collection<? extends E> c) {
1302 return addAll(this.size, c);
1303 }
1304
1305 public boolean addAll(int index, Collection<? extends E> c) {
1306 rangeCheckForAdd(index);
1307 int cSize = c.size();
1308 if (cSize == 0)
1309 return false;
1310 checkForComodification();
1311 root.addAll(offset + index, c);
1312 updateSizeAndModCount(cSize);
1313 return true;
1314 }
1315
1316 public Iterator<E> iterator() {
1317 return listIterator();
1318 }
1319
1320 public ListIterator<E> listIterator(int index) {
1321 checkForComodification();
1322 rangeCheckForAdd(index);
1323
1324 return new ListIterator<E>() {
1325 int cursor = index;
1326 int lastRet = -1;
1327 int expectedModCount = root.modCount;
1328
1329 public boolean hasNext() {
1330 return cursor != ArraySubList.this.size;
1331 }
1332
1333 @SuppressWarnings("unchecked")
1334 public E next() {
1335 checkForComodification();
1336 int i = cursor;
1337 if (i >= ArraySubList.this.size)
1338 throw new NoSuchElementException();
1339 Object[] elementData = root.elementData;
1340 if (offset + i >= elementData.length)
1341 throw new ConcurrentModificationException();
1342 cursor = i + 1;
1343 return (E) elementData[offset + (lastRet = i)];
1344 }
1345
1346 public boolean hasPrevious() {
1347 return cursor != 0;
1348 }
1349
1350 @SuppressWarnings("unchecked")
1351 public E previous() {
1352 checkForComodification();
1353 int i = cursor - 1;
1354 if (i < 0)
1355 throw new NoSuchElementException();
1356 Object[] elementData = root.elementData;
1357 if (offset + i >= elementData.length)
1358 throw new ConcurrentModificationException();
1359 cursor = i;
1360 return (E) elementData[offset + (lastRet = i)];
1361 }
1362
1363 @SuppressWarnings("unchecked")
1364 public void forEachRemaining(Consumer<? super E> consumer) {
1365 Objects.requireNonNull(consumer);
1366 final int size = ArraySubList.this.size;
1367 int i = cursor;
1368 if (i >= size) {
1369 return;
1370 }
1371 final Object[] elementData = root.elementData;
1372 if (offset + i >= elementData.length) {
1373 throw new ConcurrentModificationException();
1374 }
1375 while (i != size && modCount == expectedModCount) {
1376 consumer.accept((E) elementData[offset + (i++)]);
1377 }
1378 // update once at end of iteration to reduce heap write traffic
1379 lastRet = cursor = i;
1380 checkForComodification();
1381 }
1382
1383 public int nextIndex() {
1384 return cursor;
1385 }
1386
1387 public int previousIndex() {
1388 return cursor - 1;
1389 }
1390
1391 public void remove() {
1392 if (lastRet < 0)
1393 throw new IllegalStateException();
1394 checkForComodification();
1395
1396 try {
1397 ArraySubList.this.remove(lastRet);
1398 cursor = lastRet;
1399 lastRet = -1;
1400 expectedModCount = root.modCount;
1401 } catch (IndexOutOfBoundsException ex) {
1402 throw new ConcurrentModificationException();
1403 }
1404 }
1405
1406 public void set(E e) {
1407 if (lastRet < 0)
1408 throw new IllegalStateException();
1409 checkForComodification();
1410
1411 try {
1412 root.set(offset + lastRet, e);
1413 } catch (IndexOutOfBoundsException ex) {
1414 throw new ConcurrentModificationException();
1415 }
1416 }
1417
1418 public void add(E e) {
1419 checkForComodification();
1420
1421 try {
1422 int i = cursor;
1423 ArraySubList.this.add(i, e);
1424 cursor = i + 1;
1425 lastRet = -1;
1426 expectedModCount = root.modCount;
1427 } catch (IndexOutOfBoundsException ex) {
1428 throw new ConcurrentModificationException();
1429 }
1430 }
1431
1432 final void checkForComodification() {
1433 if (root.modCount != expectedModCount)
1434 throw new ConcurrentModificationException();
1435 }
1436 };
1437 }
1438
1439 public List<E> subList(int fromIndex, int toIndex) {
1440 subListRangeCheck(fromIndex, toIndex, size);
1441 return new ArraySubList<>(this, fromIndex, toIndex);
1442 }
1443
1444 private void rangeCheck(int index) {
1445 if (index < 0 || index >= size)
1446 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1447 }
1448
1449 private void rangeCheckForAdd(int index) {
1450 if (index < 0 || index > size)
1451 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1452 }
1453
1454 private String outOfBoundsMsg(int index) {
1455 return "Index: " + index + ", Size: " + size;
1456 }
1457
1458 private void checkForComodification() {
1459 if (root.modCount != modCount)
1460 throw new ConcurrentModificationException();
1461 }
1462
1463 private void updateSizeAndModCount(int sizeChange) {
1464 ArraySubList<E> slist = this;
1465 do {
1466 slist.size += sizeChange;
1467 slist.modCount = root.modCount;
1468 slist = slist.parent;
1469 } while (slist != null);
1470 }
1471
1472 public Spliterator<E> spliterator() {
1473 checkForComodification();
1474 return new ArrayList.ArrayListSpliterator<>(root, offset,
1475 offset + size, modCount);
1476 }
1477 }
1478
|