--- jsr166/src/main/java/util/ArrayList.java 2016/12/02 06:41:08 1.46
+++ jsr166/src/main/java/util/ArrayList.java 2017/05/31 22:37:31 1.52
@@ -91,7 +91,7 @@ import java.util.function.UnaryOperator;
* should be used only to detect bugs.
*
*
This class is a member of the
- *
+ *
* Java Collections Framework.
*
* @param the type of elements in this list
@@ -515,15 +515,10 @@ public class ArrayList extends Abstra
*/
public E remove(int index) {
Objects.checkIndex(index, size);
+ final Object[] es = elementData;
- modCount++;
- E oldValue = elementData(index);
-
- int numMoved = size - index - 1;
- if (numMoved > 0)
- System.arraycopy(elementData, index+1, elementData, index,
- numMoved);
- elementData[--size] = null; // clear to let GC do its work
+ @SuppressWarnings("unchecked") E oldValue = (E) es[index];
+ fastRemove(es, index);
// checkInvariants();
return oldValue;
@@ -543,33 +538,35 @@ public class ArrayList extends Abstra
* @return {@code true} if this list contained the specified element
*/
public boolean remove(Object o) {
- if (o == null) {
- for (int index = 0; index < size; index++)
- if (elementData[index] == null) {
- fastRemove(index);
- return true;
- }
- } else {
- for (int index = 0; index < size; index++)
- if (o.equals(elementData[index])) {
- fastRemove(index);
- return true;
- }
+ final Object[] es = elementData;
+ final int size = this.size;
+ int i = 0;
+ found: {
+ if (o == null) {
+ for (; i < size; i++)
+ if (es[i] == null)
+ break found;
+ } else {
+ for (; i < size; i++)
+ if (o.equals(es[i]))
+ break found;
+ }
+ return false;
}
- return false;
+ fastRemove(es, i);
+ return true;
}
/**
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
- private void fastRemove(int index) {
+ private void fastRemove(Object[] es, int i) {
modCount++;
- int numMoved = size - index - 1;
- if (numMoved > 0)
- System.arraycopy(elementData, index+1, elementData, index,
- numMoved);
- elementData[--size] = null; // clear to let GC do its work
+ final int newSize;
+ if ((newSize = size - 1) > i)
+ System.arraycopy(es, i + 1, es, i, newSize - i);
+ es[size = newSize] = null;
}
/**
@@ -578,8 +575,9 @@ public class ArrayList extends Abstra
*/
public void clear() {
modCount++;
- Arrays.fill(elementData, 0, size, null);
- size = 0;
+ final Object[] es = elementData;
+ for (int to = size, i = size = 0; i < to; i++)
+ es[i] = null;
}
/**
@@ -669,13 +667,17 @@ public class ArrayList extends Abstra
outOfBoundsMsg(fromIndex, toIndex));
}
modCount++;
- final Object[] es = elementData;
- final int oldSize = size;
- System.arraycopy(es, toIndex, es, fromIndex, oldSize - toIndex);
- Arrays.fill(es, size -= (toIndex - fromIndex), oldSize, null);
+ shiftTailOverGap(elementData, fromIndex, toIndex);
// checkInvariants();
}
+ /** Erases the gap from lo to hi, by sliding down following elements. */
+ private void shiftTailOverGap(Object[] es, int lo, int hi) {
+ System.arraycopy(es, hi, es, lo, size - hi);
+ for (int to = size, i = (size -= hi - lo); i < to; i++)
+ es[i] = null;
+ }
+
/**
* A version of rangeCheck used by add and addAll.
*/
@@ -761,10 +763,8 @@ public class ArrayList extends Abstra
w += end - r;
throw ex;
} finally {
- final int oldSize = size, deleted = end - w;
- modCount += deleted;
- System.arraycopy(es, end, es, w, oldSize - end);
- Arrays.fill(es, size -= deleted, oldSize, null);
+ modCount += end - w;
+ shiftTailOverGap(es, w, end);
}
}
// checkInvariants();
@@ -787,7 +787,7 @@ public class ArrayList extends Abstra
int expectedModCount = modCount;
s.defaultWriteObject();
- // Write out size as capacity for behavioural compatibility with clone()
+ // Write out size as capacity for behavioral compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
@@ -1368,6 +1368,9 @@ public class ArrayList extends Abstra
}
}
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ */
@Override
public void forEach(Consumer super E> action) {
Objects.requireNonNull(action);
@@ -1437,7 +1440,7 @@ public class ArrayList extends Abstra
private int fence; // -1 until used; then one past last index
private int expectedModCount; // initialized when fence set
- /** Create new spliterator covering the given range */
+ /** Creates new spliterator covering the given range. */
ArrayListSpliterator(int origin, int fence, int expectedModCount) {
this.index = origin;
this.fence = fence;
@@ -1519,6 +1522,9 @@ public class ArrayList extends Abstra
return (bits[i >> 6] & (1L << i)) == 0;
}
+ /**
+ * @throws NullPointerException {@inheritDoc}
+ */
@Override
public boolean removeIf(Predicate super E> filter) {
return removeIf(filter, 0, size);
@@ -1553,9 +1559,7 @@ public class ArrayList extends Abstra
for (i = beg; i < end; i++)
if (isClear(deathRow, i - beg))
es[w++] = es[i];
- final int oldSize = size;
- System.arraycopy(es, end, es, w, oldSize - end);
- Arrays.fill(es, size -= (end - w), oldSize, null);
+ shiftTailOverGap(es, w, end);
// checkInvariants();
return true;
} else {