328 |
|
* this list |
329 |
|
* @throws NullPointerException if the specified array is null |
330 |
|
*/ |
331 |
+ |
@SuppressWarnings("unchecked") |
332 |
|
public <T> T[] toArray(T a[]) { |
333 |
|
Object[] elements = getArray(); |
334 |
|
int len = elements.length; |
344 |
|
|
345 |
|
// Positional Access Operations |
346 |
|
|
347 |
+ |
@SuppressWarnings("unchecked") |
348 |
+ |
private E get(Object[] a, int index) { |
349 |
+ |
return (E) a[index]; |
350 |
+ |
} |
351 |
+ |
|
352 |
|
/** |
353 |
|
* {@inheritDoc} |
354 |
|
* |
355 |
|
* @throws IndexOutOfBoundsException {@inheritDoc} |
356 |
|
*/ |
357 |
|
public E get(int index) { |
358 |
< |
return (E)(getArray()[index]); |
358 |
> |
return get(getArray(), index); |
359 |
|
} |
360 |
|
|
361 |
|
/** |
369 |
|
lock.lock(); |
370 |
|
try { |
371 |
|
Object[] elements = getArray(); |
372 |
< |
Object oldValue = elements[index]; |
372 |
> |
E oldValue = get(elements, index); |
373 |
|
|
374 |
|
if (oldValue != element) { |
375 |
|
int len = elements.length; |
380 |
|
// Not quite a no-op; ensures volatile write semantics |
381 |
|
setArray(elements); |
382 |
|
} |
383 |
< |
return (E)oldValue; |
383 |
> |
return oldValue; |
384 |
|
} finally { |
385 |
|
lock.unlock(); |
386 |
|
} |
453 |
|
try { |
454 |
|
Object[] elements = getArray(); |
455 |
|
int len = elements.length; |
456 |
< |
Object oldValue = elements[index]; |
456 |
> |
E oldValue = get(elements, index); |
457 |
|
int numMoved = len - index - 1; |
458 |
|
if (numMoved == 0) |
459 |
|
setArray(Arrays.copyOf(elements, len - 1)); |
464 |
|
numMoved); |
465 |
|
setArray(newElements); |
466 |
|
} |
467 |
< |
return (E)oldValue; |
467 |
> |
return oldValue; |
468 |
|
} finally { |
469 |
|
lock.unlock(); |
470 |
|
} |
527 |
|
* |
528 |
|
* @param fromIndex index of first element to be removed |
529 |
|
* @param toIndex index after last element to be removed |
530 |
< |
* @throws IndexOutOfBoundsException if fromIndex or toIndex out of |
531 |
< |
* range (fromIndex < 0 || fromIndex >= size() || toIndex |
526 |
< |
* > size() || toIndex < fromIndex) |
530 |
> |
* @throws IndexOutOfBoundsException if fromIndex or toIndex out of range |
531 |
> |
* (@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex}) |
532 |
|
*/ |
533 |
|
private void removeRange(int fromIndex, int toIndex) { |
534 |
|
final ReentrantLock lock = this.lock; |
537 |
|
Object[] elements = getArray(); |
538 |
|
int len = elements.length; |
539 |
|
|
540 |
< |
if (fromIndex < 0 || fromIndex >= len || |
536 |
< |
toIndex > len || toIndex < fromIndex) |
540 |
> |
if (fromIndex < 0 || toIndex > len || toIndex < fromIndex) |
541 |
|
throw new IndexOutOfBoundsException(); |
542 |
|
int newlen = len - (toIndex - fromIndex); |
543 |
|
int numMoved = len - toIndex; |
988 |
|
return cursor > 0; |
989 |
|
} |
990 |
|
|
991 |
+ |
@SuppressWarnings("unchecked") |
992 |
|
public E next() { |
993 |
|
if (! hasNext()) |
994 |
|
throw new NoSuchElementException(); |
995 |
|
return (E) snapshot[cursor++]; |
996 |
|
} |
997 |
|
|
998 |
+ |
@SuppressWarnings("unchecked") |
999 |
|
public E previous() { |
1000 |
|
if (! hasPrevious()) |
1001 |
|
throw new NoSuchElementException(); |
1042 |
|
* Returns a view of the portion of this list between |
1043 |
|
* <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive. |
1044 |
|
* The returned list is backed by this list, so changes in the |
1045 |
< |
* returned list are reflected in this list, and vice-versa. |
1040 |
< |
* While mutative operations are supported, they are probably not |
1041 |
< |
* very useful for CopyOnWriteArrayLists. |
1045 |
> |
* returned list are reflected in this list. |
1046 |
|
* |
1047 |
|
* <p>The semantics of the list returned by this method become |
1048 |
< |
* undefined if the backing list (i.e., this list) is |
1049 |
< |
* <i>structurally modified</i> in any way other than via the |
1046 |
< |
* returned list. (Structural modifications are those that change |
1047 |
< |
* the size of the list, or otherwise perturb it in such a fashion |
1048 |
< |
* that iterations in progress may yield incorrect results.) |
1048 |
> |
* undefined if the backing list (i.e., this list) is modified in |
1049 |
> |
* any way other than via the returned list. |
1050 |
|
* |
1051 |
|
* @param fromIndex low endpoint (inclusive) of the subList |
1052 |
|
* @param toIndex high endpoint (exclusive) of the subList |
1059 |
|
try { |
1060 |
|
Object[] elements = getArray(); |
1061 |
|
int len = elements.length; |
1062 |
< |
if (fromIndex < 0 || toIndex > len || fromIndex > toIndex) |
1062 |
> |
if (fromIndex < 0 || toIndex > len || fromIndex > toIndex) |
1063 |
|
throw new IndexOutOfBoundsException(); |
1064 |
|
return new COWSubList<E>(this, fromIndex, toIndex); |
1065 |
|
} finally { |
1082 |
|
* AbstractList are already so slow on COW sublists that |
1083 |
|
* adding a bit more space/time doesn't seem even noticeable. |
1084 |
|
*/ |
1085 |
< |
private static class COWSubList<E> extends AbstractList<E> { |
1085 |
> |
private static class COWSubList<E> |
1086 |
> |
extends AbstractList<E> |
1087 |
> |
implements RandomAccess |
1088 |
> |
{ |
1089 |
|
private final CopyOnWriteArrayList<E> l; |
1090 |
|
private final int offset; |
1091 |
|
private int size; |
1092 |
|
private Object[] expectedArray; |
1093 |
|
|
1094 |
|
// only call this holding l's lock |
1095 |
< |
private COWSubList(CopyOnWriteArrayList<E> list, |
1096 |
< |
int fromIndex, int toIndex) { |
1095 |
> |
COWSubList(CopyOnWriteArrayList<E> list, |
1096 |
> |
int fromIndex, int toIndex) { |
1097 |
|
l = list; |
1098 |
|
expectedArray = l.getArray(); |
1099 |
|
offset = fromIndex; |
1193 |
|
} |
1194 |
|
} |
1195 |
|
|
1196 |
+ |
public boolean remove(Object o) { |
1197 |
+ |
int index = indexOf(o); |
1198 |
+ |
if (index == -1) |
1199 |
+ |
return false; |
1200 |
+ |
remove(index); |
1201 |
+ |
return true; |
1202 |
+ |
} |
1203 |
+ |
|
1204 |
|
public Iterator<E> iterator() { |
1205 |
|
final ReentrantLock lock = l.lock; |
1206 |
|
lock.lock(); |
1248 |
|
private final int index; |
1249 |
|
private final int offset; |
1250 |
|
private final int size; |
1251 |
< |
private COWSubListIterator(List<E> l, int index, int offset, |
1252 |
< |
int size) { |
1251 |
> |
|
1252 |
> |
COWSubListIterator(List<E> l, int index, int offset, |
1253 |
> |
int size) { |
1254 |
|
this.index = index; |
1255 |
|
this.offset = offset; |
1256 |
|
this.size = size; |