src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java
Print this page
*** 34,43 ****
--- 34,46 ----
*/
package java.util.concurrent;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
+ import java.util.function.Block;
+ import java.util.function.Predicate;
+ import java.util.function.UnaryOperator;
/**
* A thread-safe variant of {@link java.util.ArrayList} in which all mutative
* operations (<tt>add</tt>, <tt>set</tt>, and so on) are implemented by
* making a fresh copy of the underlying array.
*** 1315,1324 ****
--- 1318,1413 ----
public void add(E e) {
throw new UnsupportedOperationException();
}
}
+ @SuppressWarnings("unchecked")
+ public void forEach(Block<? super E> block) {
+ Objects.requireNonNull(block);
+ final Object[] elements = getArray();
+ for (final Object element : elements) {
+ block.accept((E) element);
+ }
+ }
+
+ @Override
+ public void sort(Comparator<? super E> c) {
+ Objects.requireNonNull(c);
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ @SuppressWarnings("unchecked")
+ final E[] elements = (E[]) getArray();
+ final E[] newElements = Arrays.copyOf(elements, elements.length);
+ Arrays.sort(newElements, c);
+ setArray(newElements);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ @Override
+ public boolean removeAll(Predicate<? super E> filter) {
+ Objects.requireNonNull(filter);
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ @SuppressWarnings("unchecked")
+ final E[] elements = (E[]) getArray();
+ final int size = elements.length;
+
+ // 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);
+ for (int i=0; i < size; i++) {
+ final E element = elements[i];
+ if (filter.test(element)) {
+ removeSet.set(i);
+ removeCount++;
+ }
+ }
+
+ // copy surviving elements into a new array
+ final boolean anyToRemove = removeCount > 0;
+ if (anyToRemove) {
+ final int newSize = size - removeCount;
+ final Object[] newElements = new Object[newSize];
+ for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
+ i = removeSet.nextClearBit(i);
+ newElements[j] = elements[i];
+ }
+ setArray(newElements);
+ }
+
+ return anyToRemove;
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ @Override
+ public void replaceAll(UnaryOperator<E> operator) {
+ Objects.requireNonNull(operator);
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ @SuppressWarnings("unchecked")
+ final E[] elements = (E[]) getArray();
+ final int len = elements.length;
+ @SuppressWarnings("unchecked")
+ final E[] newElements = (E[]) new Object[len];
+ for (int i=0; i < len; i++) {
+ newElements[i] = operator.operate(elements[i]);
+ }
+ setArray(newElements);
+ } finally {
+ lock.unlock();
+ }
+ }
+
// Support for resetting lock while deserializing
private void resetLock() {
UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());
}
private static final sun.misc.Unsafe UNSAFE;