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

Comparing jsr166/src/main/java/util/ArrayList.java (file contents):
Revision 1.38 by jsr166, Sat Nov 12 20:51:59 2016 UTC vs.
Revision 1.39 by jsr166, Sun Nov 13 02:10:09 2016 UTC

# Line 423 | Line 423 | public class ArrayList<E> extends Abstra
423          return (E) elementData[index];
424      }
425  
426 +    @SuppressWarnings("unchecked")
427 +    static <E> E elementAt(Object[] es, int index) {
428 +        return (E) es[index];
429 +    }
430 +
431      /**
432       * Returns the element at the specified position in this list.
433       *
# Line 742 | Line 747 | public class ArrayList<E> extends Abstra
747      private boolean batchRemove(Collection<?> c, boolean complement) {
748          Objects.requireNonNull(c);
749          final Object[] es = elementData;
750 <        final int size = this.size;
750 >        final int end = size;
751          final boolean modified;
752          int r;
753          // Optimize for initial run of survivors
754 <        for (r = 0; r < size && c.contains(es[r]) == complement; r++)
754 >        for (r = 0; r < end && c.contains(es[r]) == complement; r++)
755              ;
756 <        if (modified = (r < size)) {
756 >        if (modified = (r < end)) {
757              int w = r++;
758              try {
759 <                for (Object e; r < size; r++)
759 >                for (Object e; r < end; r++)
760                      if (c.contains(e = es[r]) == complement)
761                          es[w++] = e;
762              } catch (Throwable ex) {
763                  // Preserve behavioral compatibility with AbstractCollection,
764                  // even if c.contains() throws.
765 <                System.arraycopy(es, r, es, w, size - r);
766 <                w += size - r;
765 >                System.arraycopy(es, r, es, w, end - r);
766 >                w += end - r;
767                  throw ex;
768              } finally {
769 <                modCount += size - w;
770 <                Arrays.fill(es, (this.size = w), size, null);
769 >                modCount += end - w;
770 >                Arrays.fill(es, size = w, end, null);
771              }
772          }
773          return modified;
# Line 1345 | Line 1350 | public class ArrayList<E> extends Abstra
1350      public void forEach(Consumer<? super E> action) {
1351          Objects.requireNonNull(action);
1352          final int expectedModCount = modCount;
1353 <        @SuppressWarnings("unchecked")
1349 <        final E[] elementData = (E[]) this.elementData;
1353 >        final Object[] es = elementData;
1354          final int size = this.size;
1355 <        for (int i=0; modCount == expectedModCount && i < size; i++) {
1356 <            action.accept(elementData[i]);
1355 >        for (int i = 0; modCount == expectedModCount && i < size; i++) {
1356 >            action.accept(elementAt(es, i));
1357          }
1358          if (modCount != expectedModCount) {
1359              throw new ConcurrentModificationException();
# Line 1492 | Line 1496 | public class ArrayList<E> extends Abstra
1496          }
1497      }
1498  
1499 <    @SuppressWarnings("unchecked")
1499 >    // A tiny bit set implementation
1500 >
1501 >    private static long[] nBits(int n) {
1502 >        return new long[((n - 1) >> 6) + 1];
1503 >    }
1504 >    private static void setBit(long[] bits, int i) {
1505 >        bits[i >> 6] |= 1L << i;
1506 >    }
1507 >    private static boolean isClear(long[] bits, int i) {
1508 >        return (bits[i >> 6] & (1L << i)) == 0;
1509 >    }
1510 >
1511      @Override
1512 <    public boolean removeIf(Predicate<? super E> filter) {
1512 >        public boolean removeIf(Predicate<? super E> filter) {
1513          Objects.requireNonNull(filter);
1514          int expectedModCount = modCount;
1515          final Object[] es = elementData;
1516 <        final int size = this.size;
1516 >        final int end = size;
1517          final boolean modified;
1518 <        int r;
1518 >        int i;
1519          // Optimize for initial run of survivors
1520 <        for (r = 0; r < size && !filter.test((E) es[r]); r++)
1520 >        for (i = 0; i < end && !filter.test(elementAt(es, i)); i++)
1521              ;
1522 <        if (modified = (r < size)) {
1522 >        // Tolerate predicates that reentrantly access the collection for
1523 >        // read (but writers still get CME), so traverse once to find
1524 >        // elements to delete, a second pass to physically expunge.
1525 >        if (modified = (i < end)) {
1526              expectedModCount++;
1527              modCount++;
1528 <            int w = r++;
1529 <            try {
1530 <                for (E e; r < size; r++)
1531 <                    if (!filter.test(e = (E) es[r]))
1532 <                        es[w++] = e;
1533 <            } catch (Throwable ex) {
1534 <                // copy remaining elements
1535 <                System.arraycopy(es, r, es, w, size - r);
1536 <                w += size - r;
1537 <                throw ex;
1538 <            } finally {
1521 <                Arrays.fill(es, (this.size = w), size, null);
1522 <            }
1528 >            final int beg = i;
1529 >            final long[] deathRow = nBits(end - beg);
1530 >            deathRow[0] = 1L;   // set bit 0
1531 >            for (i = beg + 1; i < end; i++)
1532 >                if (filter.test(elementAt(es, i)))
1533 >                    setBit(deathRow, i - beg);
1534 >            int w = beg;
1535 >            for (i = beg; i < end; i++)
1536 >                if (isClear(deathRow, i - beg))
1537 >                    es[w++] = es[i];
1538 >            Arrays.fill(es, size = w, end, null);
1539          }
1540          if (modCount != expectedModCount)
1541              throw new ConcurrentModificationException();
# Line 1527 | Line 1543 | public class ArrayList<E> extends Abstra
1543      }
1544  
1545      @Override
1530    @SuppressWarnings("unchecked")
1546      public void replaceAll(UnaryOperator<E> operator) {
1547          Objects.requireNonNull(operator);
1548          final int expectedModCount = modCount;
1549 +        final Object[] es = elementData;
1550          final int size = this.size;
1551          for (int i=0; modCount == expectedModCount && i < size; i++) {
1552 <            elementData[i] = operator.apply((E) elementData[i]);
1552 >            es[i] = operator.apply(elementAt(es, i));
1553          }
1554          if (modCount != expectedModCount) {
1555              throw new ConcurrentModificationException();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines