copyonwritearraylist.java
来自「用applet实现很多应用小程序」· Java 代码 · 共 1,242 行 · 第 1/4 页
JAVA
1,242 行
return cursor > 0;
}
public Object next() {
try {
return (snapshot[cursor++]);
} catch (IndexOutOfBoundsException ex) {
throw new NoSuchElementException();
}
}
public Object previous() {
try {
return (snapshot[--cursor]);
} catch (IndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
/**
* Not supported. Always throws UnsupportedOperationException.
* @throws UnsupportedOperationException always; <tt>remove</tt>
* is not supported by this iterator.
*/
public void remove() {
throw new UnsupportedOperationException();
}
/**
* Not supported. Always throws UnsupportedOperationException.
* @throws UnsupportedOperationException always; <tt>set</tt>
* is not supported by this iterator.
*/
public void set(Object e) {
throw new UnsupportedOperationException();
}
/**
* Not supported. Always throws UnsupportedOperationException.
* @throws UnsupportedOperationException always; <tt>add</tt>
* is not supported by this iterator.
*/
public void add(Object e) {
throw new UnsupportedOperationException();
}
}
/**
* Returns a view of the portion of this list between
* <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
* The returned list is backed by this list, so changes in the
* returned list are reflected in this list, and vice-versa.
* While mutative operations are supported, they are probably not
* very useful for CopyOnWriteArrayLists.
*
* <p>The semantics of the list returned by this method become
* undefined if the backing list (i.e., this list) is
* <i>structurally modified</i> in any way other than via the
* returned list. (Structural modifications are those that change
* the size of the list, or otherwise perturb it in such a fashion
* that iterations in progress may yield incorrect results.)
*
* @param fromIndex low endpoint (inclusive) of the subList
* @param toIndex high endpoint (exclusive) of the subList
* @return a view of the specified range within this list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public synchronized List subList(int fromIndex, int toIndex) {
Object[] elements = getArray();
int len = elements.length;
if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
throw new IndexOutOfBoundsException();
return new COWSubList(this, fromIndex, toIndex);
}
/**
* Sublist for CopyOnWriteArrayList.
* This class extends AbstractList merely for convenience, to
* avoid having to define addAll, etc. This doesn't hurt, but
* is wasteful. This class does not need or use modCount
* mechanics in AbstractList, but does need to check for
* concurrent modification using similar mechanics. On each
* operation, the array that we expect the backing list to use
* is checked and updated. Since we do this for all of the
* base operations invoked by those defined in AbstractList,
* all is well. While inefficient, this is not worth
* improving. The kinds of list operations inherited from
* AbstractList are already so slow on COW sublists that
* adding a bit more space/time doesn't seem even noticeable.
*/
private static class COWSubList extends AbstractList {
private final CopyOnWriteArrayList l;
private final int offset;
private int size;
private Object[] expectedArray;
// only call this holding l's lock
private COWSubList(CopyOnWriteArrayList list,
int fromIndex, int toIndex) {
l = list;
expectedArray = l.getArray();
offset = fromIndex;
size = toIndex - fromIndex;
}
// only call this holding l's lock
private void checkForComodification() {
if (l.getArray() != expectedArray)
throw new ConcurrentModificationException();
}
// only call this holding l's lock
private void rangeCheck(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: " + index +
",Size: " + size);
}
public Object set(int index, Object element) {
synchronized (l) {
rangeCheck(index);
checkForComodification();
Object x = l.set(index + offset, element);
expectedArray = l.getArray();
return x;
}
}
public Object get(int index) {
synchronized (l) {
rangeCheck(index);
checkForComodification();
return l.get(index + offset);
}
}
public int size() {
synchronized (l) {
checkForComodification();
return size;
}
}
public void add(int index, Object element) {
synchronized (l) {
checkForComodification();
if (index<0 || index>size)
throw new IndexOutOfBoundsException();
l.add(index + offset, element);
expectedArray = l.getArray();
size++;
}
}
public void clear() {
synchronized (l) {
checkForComodification();
l.removeRange(offset, offset+size);
expectedArray = l.getArray();
size = 0;
}
}
public Object remove(int index) {
synchronized (l) {
rangeCheck(index);
checkForComodification();
Object result = l.remove(index + offset);
expectedArray = l.getArray();
size--;
return result;
}
}
public Iterator iterator() {
synchronized (l) {
checkForComodification();
return new COWSubListIterator(l, 0, offset, size);
}
}
public ListIterator listIterator(final int index) {
synchronized (l) {
checkForComodification();
if (index<0 || index>size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
return new COWSubListIterator(l, index, offset, size);
}
}
public List subList(int fromIndex, int toIndex) {
synchronized (l) {
checkForComodification();
if (fromIndex<0 || toIndex>size)
throw new IndexOutOfBoundsException();
return new COWSubList(l, fromIndex + offset,
toIndex + offset);
}
}
}
private static class COWSubListIterator implements ListIterator {
private final ListIterator i;
private final int offset;
private final int size;
private COWSubListIterator(List l, int index, int offset,
int size) {
this.offset = offset;
this.size = size;
i = l.listIterator(index + offset);
}
public boolean hasNext() {
return nextIndex() < size;
}
public Object next() {
if (hasNext())
return i.next();
else
throw new NoSuchElementException();
}
public boolean hasPrevious() {
return previousIndex() >= 0;
}
public Object previous() {
if (hasPrevious())
return i.previous();
else
throw new NoSuchElementException();
}
public int nextIndex() {
return i.nextIndex() - offset;
}
public int previousIndex() {
return i.previousIndex() - offset;
}
public void remove() {
throw new UnsupportedOperationException();
}
public void set(Object e) {
throw new UnsupportedOperationException();
}
public void add(Object e) {
throw new UnsupportedOperationException();
}
}
// // Support for resetting lock while deserializing
// private static final Unsafe unsafe = Unsafe.getUnsafe();
// private static final long lockOffset;
// static {
// try {
// lockOffset = unsafe.objectFieldOffset
// (CopyOnWriteArrayList.class.getDeclaredField("lock"));
// } catch (Exception ex) { throw new Error(ex); }
// }
// private void resetLock() {
// unsafe.putObjectVolatile(this, lockOffset, new ReentrantLock());
// }
//
// Temporary emulations of anticipated new j.u.Arrays functions
private static Object[] copyOfRange(Object[] original, int from, int to,
Class newType) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
Object[] copy = (Object[]) java.lang.reflect.Array.newInstance
(newType.getComponentType(), newLength);
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
private static Object[] copyOf(Object[] original, int newLength,
Class newType) {
Object[] copy = (Object[]) java.lang.reflect.Array.newInstance
(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
private static Object[] copyOf(Object[] original, int newLength) {
return copyOf(original, newLength, original.getClass());
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?