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

Print this page

        

*** 23,32 **** --- 23,36 ---- * questions. */ package java.util; + import java.util.function.Block; + import java.util.function.Predicate; + import java.util.function.UnaryOperator; + /** * Resizable-array implementation of the <tt>List</tt> interface. Implements * all optional list operations, and permits all elements, including * <tt>null</tt>. In addition to implementing the <tt>List</tt> interface, * this class provides methods to manipulate the size of the array that is
*** 1126,1131 **** --- 1130,1221 ---- private void checkForComodification() { if (ArrayList.this.modCount != this.modCount) throw new ConcurrentModificationException(); } } + + @Override + public void forEach(Block<? super E> block) { + Objects.requireNonNull(block); + final int expectedModCount = modCount; + final E[] elementData = (E[]) this.elementData; + final int size = this.size; + for (int i=0; modCount == expectedModCount && i < size; i++) { + block.accept(elementData[i]); + } + if (modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + } + + @Override + public boolean removeAll(Predicate<? super E> filter) { + Objects.requireNonNull(filter); + // figure out which elements are to be removed + // any exception thrown from the filter predicate at this stage + // will leave the collection unmodified + int removeCount = 0; + final BitSet removeSet = new BitSet(size); + final int expectedModCount = modCount; + final int size = this.size; + for (int i=0; modCount == expectedModCount && i < size; i++) { + @SuppressWarnings("unchecked") + final E element = (E) elementData[i]; + if (filter.test(element)) { + removeSet.set(i); + removeCount++; + } + } + + if (modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + + // shift surviving elements left over the spaces left by removed elements + final boolean anyToRemove = removeCount > 0; + if (anyToRemove) { + final int newSize = size - removeCount; + for (int i=0, j=0; modCount == expectedModCount && + (i < size) && (j < newSize); i++, j++) { + i = removeSet.nextClearBit(i); + elementData[j] = elementData[i]; + } + for (int k=newSize; modCount == expectedModCount && k < size; k++) { + elementData[k] = null; // Let gc do its work + } + this.size = newSize; + if (modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + modCount++; + } + + return anyToRemove; + } + + @Override + @SuppressWarnings("unchecked") + public void replaceAll(UnaryOperator<E> operator) { + Objects.requireNonNull(operator); + final int expectedModCount = modCount; + final int size = this.size; + for (int i=0; modCount == expectedModCount && i < size; i++) { + elementData[i] = operator.operate((E) elementData[i]); + } + if (modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + modCount++; + } + + @Override + @SuppressWarnings("unchecked") + public void sort(Comparator<? super E> c) { + Objects.requireNonNull(c); + final int expectedModCount = modCount; + Arrays.sort((E[]) elementData, 0, size, c); + if (modCount != expectedModCount) { + throw new ConcurrentModificationException(); + } + modCount++; + } }