📄 copyonwritearraylist.java
字号:
StringBuffer buf = new StringBuffer(); Iterator e = iterator(); buf.append("["); int maxIndex = size() - 1; for (int i = 0; i <= maxIndex; i++) { buf.append(String.valueOf(e.next())); if (i < maxIndex) { buf.append(", "); } } buf.append("]"); return buf.toString(); } /** * Compares the specified Object with this List for equality. Returns true if and only if the * specified Object is also a List, both Lists have the same size, and all corresponding pairs * of elements in the two Lists are <em>equal</em>. (Two elements <code>e1</code> and * <code>e2</code> are <em>equal</em> if <code>(e1==null ? e2==null : e1.equals(e2))</code>.) * In other words, two Lists are defined to be equal if they contain the same elements in the * same order. * <p> * This implementation first checks if the specified object is this List. If so, it returns * true; if not, it checks if the specified object is a List. If not, it returns false; if so, * it iterates over both lists, comparing corresponding pairs of elements. If any comparison * returns false, this method returns false. If either Iterator runs out of elements before * before the other it returns false (as the Lists are of unequal length); otherwise it returns * true when the iterations complete. * * @param o * the Object to be compared for equality with this List. * @return true if the specified Object is equal to this List. */ public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof List)) { return false; } List l2 = (List)(o); if (size() != l2.size()) { return false; } ListIterator e1 = listIterator(); ListIterator e2 = l2.listIterator(); while (e1.hasNext()) { Object o1 = e1.next(); Object o2 = e2.next(); if (!(o1 == null ? o2 == null : o1.equals(o2))) { return false; } } return true; } /** * Returns the hash code value for this List. * <p> * This implementation uses exactly the code that is used to define the List hash function in * the documentation for List.hashCode. */ public int hashCode() { int hashCode = 1; Iterator i = iterator(); while (i.hasNext()) { Object obj = i.next(); hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); } return hashCode; } /** * Returns an Iterator over the elements contained in this collection. The iterator provides a * snapshot of the state of the list when the iterator was constructed. No synchronization is * needed while traversing the iterator. The iterator does <em>NOT</em> support the * <code>remove</code> method. */ public Iterator iterator() { return new COWIterator(array(), 0); } /** * Returns an Iterator of the elements in this List (in proper sequence). The iterator provides * a snapshot of the state of the list when the iterator was constructed. No synchronization is * needed while traversing the iterator. The iterator does <em>NOT</em> support the * <code>remove</code>, <code>set</code>, or <code>add</code> methods. * */ public ListIterator listIterator() { return new COWIterator(array(), 0); } /** * Returns a ListIterator of the elements in this List (in proper sequence), starting at the * specified position in the List. The specified index indicates the first element that would be * returned by an initial call to nextElement. An initial call to previousElement would return * the element with the specified index minus one. The ListIterator returned by this * implementation will throw an UnsupportedOperationException in its remove, set and add * methods. * * @param index * index of first element to be returned from the ListIterator (by a call to * getNext). * @exception IndexOutOfBoundsException * index is out of range (index < 0 || index > size()). */ public ListIterator listIterator(final int index) { Object[] elementData = array(); int len = elementData.length; if (index < 0 || index > len) { throw new IndexOutOfBoundsException("Index: " + index); } return new COWIterator(array(), index); } protected static class COWIterator implements ListIterator { /** Snapshot of the array * */ protected final Object[] array; /** * Index of element to be returned by subsequent call to next. */ protected int cursor; protected COWIterator(Object[] elementArray, int initialCursor) { array = elementArray; cursor = initialCursor; } public boolean hasNext() { return cursor < array.length; } public boolean hasPrevious() { return cursor > 0; } public Object next() { try { return array[cursor++]; } catch (IndexOutOfBoundsException ex) { throw new NoSuchElementException(); } } public Object previous() { try { return array[--cursor]; } catch (IndexOutOfBoundsException e) { throw new NoSuchElementException(); } } public int nextIndex() { return cursor; } public int previousIndex() { return cursor - 1; } /** * Not supported. Always throws UnsupportedOperationException. * * @exception UnsupportedOperationException * remove is not supported by this Iterator. */ public void remove() { throw new UnsupportedOperationException(); } /** * Not supported. Always throws UnsupportedOperationException. * * @exception UnsupportedOperationException * set is not supported by this Iterator. */ public void set(Object o) { throw new UnsupportedOperationException(); } /** * Not supported. Always throws UnsupportedOperationException. * * @exception UnsupportedOperationException * add is not supported by this Iterator. */ public void add(Object o) { throw new UnsupportedOperationException(); } } /** * Returns a view of the portion of this List between fromIndex, inclusive, and toIndex, * 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 CopyOnWriteArrays. * </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 toKey * high endpoint (exclusive) of the subList. * @return a view of the specified range within this List. * @exception IndexOutOfBoundsException * Illegal endpoint index value (fromIndex < 0 || toIndex > size || * fromIndex > toIndex). */ public synchronized List subList(int fromIndex, int toIndex) { // synchronized since sublist ctor depends on it. int len = array_.length; if (fromIndex < 0 || toIndex > len || fromIndex > toIndex) { throw new IndexOutOfBoundsException(); } return new COWSubList(this, fromIndex, toIndex); } protected static class COWSubList extends AbstractList { /* * This is currently a bit sleazy. The class extends AbstractList merely for convenience, to * avoid having to define addAll, etc. This doesn't hurt, but is stupid and 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. * * It's not clear whether this is worth cleaning up. The kinds of list operations inherited * from AbstractList are are already so slow on COW sublists that adding a bit more * space/time doesn't seem even noticeable. */ protected final CopyOnWriteArrayList l; protected final int offset; protected int size; protected Object[] expectedArray; protected COWSubList(CopyOnWriteArrayList list, int fromIndex, int toIndex) { l = list; expectedArray = l.array(); offset = fromIndex; size = toIndex - fromIndex; } // only call this holding l's lock protected void checkForComodification() { if (l.array_ != expectedArray) { throw new ConcurrentModificationException(); } } // only call this holding l's lock protected 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.array_; 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.array_; size++; } } public Object remove(int index) { synchronized (l) { rangeCheck(index); checkForComodification(); Object result = l.remove(index + offset); expectedArray = l.array_; size--; return result; } } public Iterator iterator() { synchronized (l) { checkForComodification(); return new COWSubListIterator(0); } } public ListIterator listIterator(final int index) { synchronized (l) { checkForComodification(); if (index < 0 || index > size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } return new COWSubListIterator(index); } } protected class COWSubListIterator implements ListIterator { protected final ListIterator i; protected final int index; protected COWSubListIterator(int index) { this.index = index; 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 o) { throw new UnsupportedOperationException(); } public void add(Object o) { throw new UnsupportedOperationException(); } } 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); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -