Methods Summary |
---|
public synchronized boolean | add(E element)Appends the specified element to the end of this list.
int len = array.length;
E[] newArray = (E[]) new Object[len+1];
System.arraycopy(array, 0, newArray, 0, len);
newArray[len] = element;
array = newArray;
return true;
|
public synchronized void | add(int index, E element)Inserts the specified element at the specified position in this
list. Shifts the element currently at that position (if any) and
any subsequent elements to the right (adds one to their indices).
int len = array.length;
if (index > len || index < 0)
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+len);
E[] newArray = (E[]) new Object[len+1];
System.arraycopy(array, 0, newArray, 0, index);
newArray[index] = element;
System.arraycopy(array, index, newArray, index+1, len - index);
array = newArray;
|
public synchronized boolean | addAll(java.util.Collection c)Appends all of the elements in the specified Collection to the end of
this list, in the order that they are returned by the
specified Collection's Iterator.
int numNew = c.size();
if (numNew == 0) return false;
int len = array.length;
E[] newArray = (E[]) new Object[len+numNew];
System.arraycopy(array, 0, newArray, 0, len);
Iterator<? extends E> e = c.iterator();
for (int i=0; i<numNew; i++)
newArray[len++] = e.next();
array = newArray;
return true;
|
public synchronized boolean | addAll(int index, java.util.Collection c)Inserts all of the elements in the specified Collection into this
list, starting at the specified position. Shifts the element
currently at that position (if any) and any subsequent elements to
the right (increases their indices). The new elements will appear
in the list in the order that they are returned by the
specified Collection's iterator.
int len = array.length;
if (index > len || index < 0)
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+len);
int numNew = c.size();
if (numNew == 0) return false;
E[] newArray = (E[]) new Object[len+numNew];
System.arraycopy(array, 0, newArray, 0, len);
int numMoved = len - index;
if (numMoved > 0)
System.arraycopy(array, index, newArray, index + numNew, numMoved);
Iterator<? extends E> e = c.iterator();
for (int i=0; i<numNew; i++)
newArray[index++] = e.next();
array = newArray;
return true;
|
public synchronized int | addAllAbsent(java.util.Collection c)Appends all of the elements in the specified Collection that
are not already contained in this list, to the end of
this list, in the order that they are returned by the
specified Collection's Iterator.
int numNew = c.size();
if (numNew == 0) return 0;
E[] elementData = array;
int len = elementData.length;
E[] temp = (E[]) new Object[numNew];
int added = 0;
Iterator<? extends E> e = c.iterator();
while (e.hasNext()) {
E element = e.next();
if (indexOf(element, elementData, len) < 0) {
if (indexOf(element, temp, added) < 0) {
temp[added++] = element;
}
}
}
if (added == 0) return 0;
E[] newArray = (E[]) new Object[len+added];
System.arraycopy(elementData, 0, newArray, 0, len);
System.arraycopy(temp, 0, newArray, len, added);
array = newArray;
return added;
|
public synchronized boolean | addIfAbsent(E element)Append the element if not present.
// Copy while checking if already present.
// This wins in the most common case where it is not present
int len = array.length;
E[] newArray = (E[]) new Object[len + 1];
for (int i = 0; i < len; ++i) {
if (element == array[i] ||
(element != null && element.equals(array[i])))
return false; // exit, throwing away copy
else
newArray[i] = array[i];
}
newArray[len] = element;
array = newArray;
return true;
|
private E[] | array()Accessor to the array intended to be called from
within unsynchronized read-only methods
return array;
|
public synchronized void | clear()Removes all of the elements from this list.
array = (E[]) new Object[0];
|
public java.lang.Object | clone()Returns a shallow copy of this list. (The elements themselves
are not copied.)
try {
E[] elementData = array();
CopyOnWriteArrayList<E> v = (CopyOnWriteArrayList<E>)super.clone();
v.array = (E[]) new Object[elementData.length];
System.arraycopy(elementData, 0, v.array, 0, elementData.length);
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
|
public boolean | contains(java.lang.Object elem)Returns true if this list contains the specified element.
E[] elementData = array();
int len = elementData.length;
return indexOf(elem, elementData, len) >= 0;
|
public boolean | containsAll(java.util.Collection c)Returns true if this Collection contains all of the elements in the
specified Collection.
This implementation iterates over the specified Collection, checking
each element returned by the Iterator in turn to see if it's
contained in this Collection. If all elements are so contained
true is returned, otherwise false.
E[] elementData = array();
int len = elementData.length;
Iterator e = c.iterator();
while (e.hasNext())
if (indexOf(e.next(), elementData, len) < 0)
return false;
return true;
|
private synchronized void | copyIn(E[] toCopyIn, int first, int n)Replace the held array with a copy of the n elements
of the provided array, starting at position first. To
copy an entire array, call with arguments (array, 0,
array.length).
array = (E[]) new Object[n];
System.arraycopy(toCopyIn, first, array, 0, n);
|
public boolean | equals(java.lang.Object o)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
equal. (Two elements e1 and e2 are
equal if (e1==null ? e2==null : e1.equals(e2)).)
In other words, two Lists are defined to be equal if they contain the
same elements in the same order.
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 the other it returns false
(as the Lists are of unequal length); otherwise it returns true when
the iterations complete.
if (o == this)
return true;
if (!(o instanceof List))
return false;
List<E> l2 = (List<E>)(o);
if (size() != l2.size())
return false;
ListIterator<E> e1 = listIterator();
ListIterator<E> e2 = l2.listIterator();
while(e1.hasNext()) {
E o1 = e1.next();
E o2 = e2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return true;
|
public E | get(int index)Returns the element at the specified position in this list.
E[] elementData = array();
rangeCheck(index, elementData.length);
return elementData[index];
|
public int | hashCode()Returns the hash code value for this List.
This implementation uses the definition in {@link
List#hashCode}.
int hashCode = 1;
Iterator<E> i = iterator();
while (i.hasNext()) {
E obj = i.next();
hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
}
return hashCode;
|
private static int | indexOf(java.lang.Object elem, java.lang.Object[] elementData, int len)static version allows repeated call without needed
to grab lock for array each time
if (elem == null) {
for (int i = 0; i < len; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < len; i++)
if (elem.equals(elementData[i]))
return i;
}
return -1;
|
public int | indexOf(E elem, int index)Searches for the first occurrence of the given argument, beginning
the search at index, and testing for equality using
the equals method.
E[] elementData = array();
int elementCount = elementData.length;
if (elem == null) {
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = index ; i < elementCount ; i++)
if (elem.equals(elementData[i]))
return i;
}
return -1;
|
public int | indexOf(java.lang.Object elem)Searches for the first occurrence of the given argument, testing
for equality using the equals method.
E[] elementData = array();
int len = elementData.length;
return indexOf(elem, elementData, len);
|
public boolean | isEmpty()Tests if this list has no elements.
return size() == 0;
|
public java.util.Iterator | iterator()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
NOT support the remove method.
return new COWIterator<E>(array(), 0);
|
public int | lastIndexOf(java.lang.Object elem)Returns the index of the last occurrence of the specified object in
this list.
E[] elementData = array();
int len = elementData.length;
return lastIndexOf(elem, elementData, len);
|
private static int | lastIndexOf(java.lang.Object elem, java.lang.Object[] elementData, int len)
if (elem == null) {
for (int i = len-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = len-1; i >= 0; i--)
if (elem.equals(elementData[i]))
return i;
}
return -1;
|
public int | lastIndexOf(E elem, int index)Searches backwards for the specified object, starting from the
specified index, and returns an index to it.
// needed in order to compile on 1.2b3
E[] elementData = array();
if (elem == null) {
for (int i = index; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = index; i >= 0; i--)
if (elem.equals(elementData[i]))
return i;
}
return -1;
|
public java.util.ListIterator | listIterator()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
NOT support the remove, set,
or add methods.
return new COWIterator<E>(array(), 0);
|
public java.util.ListIterator | listIterator(int index)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.
E[] elementData = array();
int len = elementData.length;
if (index<0 || index>len)
throw new IndexOutOfBoundsException("Index: "+index);
return new COWIterator<E>(array(), index);
|
private void | rangeCheck(int index, int length)Check if the given index is in range. If not, throw an appropriate
runtime exception.
if (index >= length || index < 0)
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+ length);
|
private void | readObject(java.io.ObjectInputStream s)Reconstitute the list from a stream (i.e., deserialize it).
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in array length and allocate array
int arrayLength = s.readInt();
E[] elementData = (E[]) new Object[arrayLength];
// Read in all elements in the proper order.
for (int i=0; i<elementData.length; i++)
elementData[i] = (E) s.readObject();
array = elementData;
|
public synchronized E | remove(int index)Removes the element at the specified position in this list.
Shifts any subsequent elements to the left (subtracts one from their
indices).
int len = array.length;
rangeCheck(index, len);
E oldValue = array[index];
E[] newArray = (E[]) new Object[len-1];
System.arraycopy(array, 0, newArray, 0, index);
int numMoved = len - index - 1;
if (numMoved > 0)
System.arraycopy(array, index+1, newArray, index, numMoved);
array = newArray;
return oldValue;
|
public synchronized boolean | remove(java.lang.Object o)Removes a single instance of the specified element from this
list, if it is present (optional operation). More formally,
removes an element e such that (o==null ? e==null :
o.equals(e)), if the list contains one or more such
elements. Returns true if the list contained the
specified element (or equivalently, if the list changed as a
result of the call).
int len = array.length;
if (len == 0) return false;
// Copy while searching for element to remove
// This wins in the normal case of element being present
int newlen = len-1;
E[] newArray = (E[]) new Object[newlen];
for (int i = 0; i < newlen; ++i) {
if (o == array[i] ||
(o != null && o.equals(array[i]))) {
// found one; copy remaining and exit
for (int k = i + 1; k < len; ++k) newArray[k-1] = array[k];
array = newArray;
return true;
} else
newArray[i] = array[i];
}
// special handling for last cell
if (o == array[newlen] ||
(o != null && o.equals(array[newlen]))) {
array = newArray;
return true;
} else
return false; // throw away copy
|
public synchronized boolean | removeAll(java.util.Collection c)Removes from this Collection all of its elements that are contained in
the specified Collection. This is a particularly expensive operation
in this class because of the need for an internal temporary array.
E[] elementData = array;
int len = elementData.length;
if (len == 0) return false;
// temp array holds those elements we know we want to keep
E[] temp = (E[]) new Object[len];
int newlen = 0;
for (int i = 0; i < len; ++i) {
E element = elementData[i];
if (!c.contains(element)) {
temp[newlen++] = element;
}
}
if (newlen == len) return false;
// copy temp as new array
E[] newArray = (E[]) new Object[newlen];
System.arraycopy(temp, 0, newArray, 0, newlen);
array = newArray;
return true;
|
private synchronized void | removeRange(int fromIndex, int toIndex)Removes from this List all of the elements whose index is between
fromIndex, inclusive and toIndex, exclusive. Shifts any succeeding
elements to the left (reduces their index).
This call shortens the list by (toIndex - fromIndex) elements.
(If toIndex==fromIndex, this operation has no effect.)
int len = array.length;
if (fromIndex < 0 || fromIndex >= len ||
toIndex > len || toIndex < fromIndex)
throw new IndexOutOfBoundsException();
int numMoved = len - toIndex;
int newlen = len - (toIndex-fromIndex);
E[] newArray = (E[]) new Object[newlen];
System.arraycopy(array, 0, newArray, 0, fromIndex);
System.arraycopy(array, toIndex, newArray, fromIndex, numMoved);
array = newArray;
|
public synchronized boolean | retainAll(java.util.Collection c)Retains only the elements in this Collection that are contained in the
specified Collection (optional operation). In other words, removes from
this Collection all of its elements that are not contained in the
specified Collection.
E[] elementData = array;
int len = elementData.length;
if (len == 0) return false;
E[] temp = (E[]) new Object[len];
int newlen = 0;
for (int i = 0; i < len; ++i) {
E element = elementData[i];
if (c.contains(element)) {
temp[newlen++] = element;
}
}
if (newlen == len) return false;
E[] newArray = (E[]) new Object[newlen];
System.arraycopy(temp, 0, newArray, 0, newlen);
array = newArray;
return true;
|
public synchronized E | set(int index, E element)Replaces the element at the specified position in this list with
the specified element.
int len = array.length;
rangeCheck(index, len);
E oldValue = array[index];
boolean same = (oldValue == element ||
(element != null && element.equals(oldValue)));
if (!same) {
E[] newArray = (E[]) new Object[len];
System.arraycopy(array, 0, newArray, 0, len);
newArray[index] = element;
array = newArray;
}
return oldValue;
|
public int | size()Returns the number of elements in this list.
return array().length;
|
public synchronized java.util.List | subList(int fromIndex, int toIndex)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 CopyOnWriteArrayLists.
The semantics of the List returned by this method become undefined if
the backing list (i.e., this List) is structurally modified 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.)
// synchronized since sublist constructor depends on it.
int len = array.length;
if (fromIndex<0 || toIndex>len || fromIndex>toIndex)
throw new IndexOutOfBoundsException();
return new COWSubList<E>(this, fromIndex, toIndex);
|
public java.lang.Object[] | toArray()Returns an array containing all of the elements in this list
in the correct order.
Object[] elementData = array();
Object[] result = new Object[elementData.length];
System.arraycopy(elementData, 0, result, 0, elementData.length);
return result;
|
public T[] | toArray(T[] a)Returns an array containing all of the elements in this list in the
correct order. The runtime type of the returned array is that of the
specified array. If the list fits in the specified array, it is
returned therein. Otherwise, a new array is allocated with the runtime
type of the specified array and the size of this list.
If the list fits in the specified array with room to spare
(i.e., the array has more elements than the list),
the element in the array immediately following the end of the
collection is set to null. This is useful in determining the length
of the list only if the caller knows that the list
does not contain any null elements.
E[] elementData = array();
if (a.length < elementData.length)
a = (T[])
java.lang.reflect.Array.newInstance(a.getClass().getComponentType(),
elementData.length);
System.arraycopy(elementData, 0, a, 0, elementData.length);
if (a.length > elementData.length)
a[elementData.length] = null;
return a;
|
public java.lang.String | toString()Returns a string representation of this Collection, containing
the String representation of each element.
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();
|
private void | writeObject(java.io.ObjectOutputStream s)Save the state of the list to a stream (i.e., serialize it).
// Write out element count, and any hidden stuff
s.defaultWriteObject();
E[] elementData = array();
// Write out array length
s.writeInt(elementData.length);
// Write out all elements in the proper order.
for (int i=0; i<elementData.length; i++)
s.writeObject(elementData[i]);
|