< prev index next >

src/java.base/share/classes/java/util/ArrayList.java

Print this page




1264             if (index < 0 || index >= this.size)
1265                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1266         }
1267 
1268         private void rangeCheckForAdd(int index) {
1269             if (index < 0 || index > this.size)
1270                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1271         }
1272 
1273         private String outOfBoundsMsg(int index) {
1274             return "Index: "+index+", Size: "+this.size;
1275         }
1276 
1277         private void checkForComodification() {
1278             if (ArrayList.this.modCount != this.modCount)
1279                 throw new ConcurrentModificationException();
1280         }
1281 
1282         public Spliterator<E> spliterator() {
1283             checkForComodification();
1284             return new ArrayListSpliterator<>(ArrayList.this, offset,
1285                                               offset + this.size, this.modCount);
1286         }
1287     }
1288 
1289     @Override
1290     public void forEach(Consumer<? super E> action) {
1291         Objects.requireNonNull(action);
1292         final int expectedModCount = modCount;
1293         @SuppressWarnings("unchecked")
1294         final E[] elementData = (E[]) this.elementData;
1295         final int size = this.size;
1296         for (int i=0; modCount == expectedModCount && i < size; i++) {
1297             action.accept(elementData[i]);
1298         }
1299         if (modCount != expectedModCount) {
1300             throw new ConcurrentModificationException();
1301         }
1302     }
1303 
1304     /**
1305      * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
1306      * and <em>fail-fast</em> {@link Spliterator} over the elements in this
1307      * list.
1308      *
1309      * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
1310      * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
1311      * Overriding implementations should document the reporting of additional
1312      * characteristic values.
1313      *
1314      * @return a {@code Spliterator} over the elements in this list
1315      * @since 1.8
1316      */
1317     @Override
1318     public Spliterator<E> spliterator() {
1319         return new ArrayListSpliterator<>(this, 0, -1, 0);
1320     }
1321 
1322     /** Index-based split-by-two, lazily initialized Spliterator */
1323     static final class ArrayListSpliterator<E> implements Spliterator<E> {
1324 
1325         /*
1326          * If ArrayLists were immutable, or structurally immutable (no
1327          * adds, removes, etc), we could implement their spliterators
1328          * with Arrays.spliterator. Instead we detect as much
1329          * interference during traversal as practical without
1330          * sacrificing much performance. We rely primarily on
1331          * modCounts. These are not guaranteed to detect concurrency
1332          * violations, and are sometimes overly conservative about
1333          * within-thread interference, but detect enough problems to
1334          * be worthwhile in practice. To carry this out, we (1) lazily
1335          * initialize fence and expectedModCount until the latest
1336          * point that we need to commit to the state we are checking
1337          * against; thus improving precision.  (This doesn't apply to
1338          * SubLists, that create spliterators with current non-lazy
1339          * values).  (2) We perform only a single
1340          * ConcurrentModificationException check at the end of forEach
1341          * (the most performance-sensitive method). When using forEach
1342          * (as opposed to iterators), we can normally only detect
1343          * interference after actions, not before. Further
1344          * CME-triggering checks apply to all other possible
1345          * violations of assumptions for example null or too-small
1346          * elementData array given its size(), that could only have
1347          * occurred due to interference.  This allows the inner loop
1348          * of forEach to run without any further checks, and
1349          * simplifies lambda-resolution. While this does entail a
1350          * number of checks, note that in the common case of
1351          * list.stream().forEach(a), no checks or other computation
1352          * occur anywhere other than inside forEach itself.  The other
1353          * less-often-used methods cannot take advantage of most of
1354          * these streamlinings.
1355          */
1356 
1357         private final ArrayList<E> list;
1358         private int index; // current index, modified on advance/split
1359         private int fence; // -1 until used; then one past last index
1360         private int expectedModCount; // initialized when fence set
1361 
1362         /** Create new spliterator covering the given  range */
1363         ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
1364                              int expectedModCount) {
1365             this.list = list; // OK if null unless traversed
1366             this.index = origin;
1367             this.fence = fence;
1368             this.expectedModCount = expectedModCount;
1369         }
1370 
1371         private int getFence() { // initialize fence to size on first use
1372             int hi; // (a specialized variant appears in method forEach)
1373             ArrayList<E> lst;

1374             if ((hi = fence) < 0) {
1375                 if ((lst = list) == null)
1376                     hi = fence = 0;
1377                 else {
1378                     expectedModCount = lst.modCount;
1379                     hi = fence = lst.size;
1380                 }




1381             }
1382             return hi;
1383         }
1384 
1385         public ArrayListSpliterator<E> trySplit() {
1386             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1387             return (lo >= mid) ? null : // divide range in half unless too small
1388                 new ArrayListSpliterator<>(list, lo, index = mid,
1389                                            expectedModCount);
1390         }
1391 
1392         public boolean tryAdvance(Consumer<? super E> action) {
1393             if (action == null)
1394                 throw new NullPointerException();
1395             int hi = getFence(), i = index;
1396             if (i < hi) {
1397                 index = i + 1;
1398                 @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
1399                 action.accept(e);
1400                 if (list.modCount != expectedModCount)
1401                     throw new ConcurrentModificationException();
1402                 return true;
1403             }
1404             return false;
1405         }
1406 
1407         public void forEachRemaining(Consumer<? super E> action) {

1408             int i, hi, mc; // hoist accesses and checks from loop
1409             ArrayList<E> lst; Object[] a;
1410             if (action == null)
1411                 throw new NullPointerException();
1412             if ((lst = list) != null && (a = lst.elementData) != null) {
1413                 if ((hi = fence) < 0) {

1414                     mc = lst.modCount;
1415                     hi = lst.size;





1416                 }
1417                 else
1418                     mc = expectedModCount;
1419                 if ((i = index) >= 0 && (index = hi) <= a.length) {
1420                     for (; i < hi; ++i) {
1421                         @SuppressWarnings("unchecked") E e = (E) a[i];
1422                         action.accept(e);
1423                     }
1424                     if (lst.modCount == mc)
1425                         return;
1426                 }
1427             }
1428             throw new ConcurrentModificationException();
1429         }
1430 
1431         public long estimateSize() {
1432             return (long) (getFence() - index);
1433         }
1434 
1435         public int characteristics() {




1264             if (index < 0 || index >= this.size)
1265                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1266         }
1267 
1268         private void rangeCheckForAdd(int index) {
1269             if (index < 0 || index > this.size)
1270                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1271         }
1272 
1273         private String outOfBoundsMsg(int index) {
1274             return "Index: "+index+", Size: "+this.size;
1275         }
1276 
1277         private void checkForComodification() {
1278             if (ArrayList.this.modCount != this.modCount)
1279                 throw new ConcurrentModificationException();
1280         }
1281 
1282         public Spliterator<E> spliterator() {
1283             checkForComodification();
1284             return new ArrayListSpliterator(this, offset, -1, 0);

1285         }
1286     }
1287 
1288     @Override
1289     public void forEach(Consumer<? super E> action) {
1290         Objects.requireNonNull(action);
1291         final int expectedModCount = modCount;
1292         @SuppressWarnings("unchecked")
1293         final E[] elementData = (E[]) this.elementData;
1294         final int size = this.size;
1295         for (int i=0; modCount == expectedModCount && i < size; i++) {
1296             action.accept(elementData[i]);
1297         }
1298         if (modCount != expectedModCount) {
1299             throw new ConcurrentModificationException();
1300         }
1301     }
1302 
1303     /**
1304      * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
1305      * and <em>fail-fast</em> {@link Spliterator} over the elements in this
1306      * list.
1307      *
1308      * <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
1309      * {@link Spliterator#SUBSIZED}, and {@link Spliterator#ORDERED}.
1310      * Overriding implementations should document the reporting of additional
1311      * characteristic values.
1312      *
1313      * @return a {@code Spliterator} over the elements in this list
1314      * @since 1.8
1315      */
1316     @Override
1317     public Spliterator<E> spliterator() {
1318         return new ArrayListSpliterator(null, 0, -1, 0);
1319     }
1320 
1321     /** Index-based split-by-two, lazily initialized Spliterator */
1322     final class ArrayListSpliterator implements Spliterator<E> {
1323 
1324         /*
1325          * If ArrayLists were immutable, or structurally immutable (no
1326          * adds, removes, etc), we could implement their spliterators
1327          * with Arrays.spliterator. Instead we detect as much
1328          * interference during traversal as practical without
1329          * sacrificing much performance. We rely primarily on
1330          * modCounts. These are not guaranteed to detect concurrency
1331          * violations, and are sometimes overly conservative about
1332          * within-thread interference, but detect enough problems to
1333          * be worthwhile in practice. To carry this out, we (1) lazily
1334          * initialize fence and expectedModCount until the latest
1335          * point that we need to commit to the state we are checking
1336          * against; thus improving precision.  (This doesn't apply to
1337          * SubLists, that create spliterators with current non-lazy
1338          * values).  (2) We perform only a single
1339          * ConcurrentModificationException check at the end of forEach
1340          * (the most performance-sensitive method). When using forEach
1341          * (as opposed to iterators), we can normally only detect
1342          * interference after actions, not before. Further
1343          * CME-triggering checks apply to all other possible
1344          * violations of assumptions for example null or too-small
1345          * elementData array given its size(), that could only have
1346          * occurred due to interference.  This allows the inner loop
1347          * of forEach to run without any further checks, and
1348          * simplifies lambda-resolution. While this does entail a
1349          * number of checks, note that in the common case of
1350          * list.stream().forEach(a), no checks or other computation
1351          * occur anywhere other than inside forEach itself.  The other
1352          * less-often-used methods cannot take advantage of most of
1353          * these streamlinings.
1354          */
1355 
1356         private final SubList subList;
1357         private int index; // current index, modified on advance/split
1358         private int fence; // -1 until used; then one past last index
1359         private int expectedModCount; // initialized when fence set
1360 
1361         /** Create new spliterator covering the given  range */
1362         ArrayListSpliterator(SubList subList, int origin, 
1363                              int fence, int expectedModCount) {
1364             this.subList = subList;
1365             this.index = origin;
1366             this.fence = fence;
1367             this.expectedModCount = expectedModCount;
1368         }
1369 
1370         private int getFence() { // initialize fence to size on first use
1371             int hi; // (a specialized variant appears in method forEach)
1372             ArrayList<E> lst;
1373             SubList subLst;
1374             if ((hi = fence) < 0) {
1375                 if ((subLst = subList) == null) {
1376                     lst = ArrayList.this;

1377                     expectedModCount = lst.modCount;
1378                     hi = fence = lst.size;
1379                 }
1380                 else {
1381                     expectedModCount = subLst.modCount;
1382                     hi = fence = subLst.offset + subLst.size;
1383                 }
1384             }
1385             return hi;
1386         }
1387 
1388         public ArrayListSpliterator trySplit() {
1389             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1390             return (lo >= mid) ? null : // divide range in half unless too small
1391                 new ArrayListSpliterator(null, lo, index = mid,
1392                                            expectedModCount);
1393         }
1394 
1395         public boolean tryAdvance(Consumer<? super E> action) {
1396             Objects.requireNonNull(action);

1397             int hi = getFence(), i = index;
1398             if (i < hi) {
1399                 index = i + 1;
1400                 @SuppressWarnings("unchecked") E e = (E)elementData[i];
1401                 action.accept(e);
1402                 if (ArrayList.this.modCount != expectedModCount)
1403                     throw new ConcurrentModificationException();
1404                 return true;
1405             }
1406             return false;
1407         }
1408 
1409         public void forEachRemaining(Consumer<? super E> action) {
1410             Objects.requireNonNull(action);
1411             int i, hi, mc; // hoist accesses and checks from loop
1412             ArrayList<E> lst = ArrayList.this;
1413             SubList subLst;
1414             Object[] a;
1415             if ((a = lst.elementData) != null) {
1416                 if ((hi = fence) < 0) {
1417                     if ((subLst = subList) == null) {
1418                         mc = lst.modCount;
1419                         hi = lst.size;
1420                     }
1421                     else {
1422                         mc = subLst.modCount;
1423                         hi = subLst.offset + subLst.size;
1424                     }
1425                 }
1426                 else
1427                     mc = expectedModCount;
1428                 if ((i = index) >= 0 && (index = hi) <= a.length) {
1429                     for (; i < hi; ++i) {
1430                         @SuppressWarnings("unchecked") E e = (E) a[i];
1431                         action.accept(e);
1432                     }
1433                     if (lst.modCount == mc)
1434                         return;
1435                 }
1436             }
1437             throw new ConcurrentModificationException();
1438         }
1439 
1440         public long estimateSize() {
1441             return (long) (getFence() - index);
1442         }
1443 
1444         public int characteristics() {


< prev index next >