A DESCRIPTION OF THE REQUEST :
The CopyOnWrite collections are very useful, however they are difficult to use if your code logic needs to make more than one call on the collection within a logical operation because the contents of the collection could change between each call. These collections should provide "snapshot()" methods which return cheap, unmodifiable copies which will never be altered by changes to the original collection. Thus, code which needs to make more than one call on a collection could snapshot the collection before proceeding. A snapshot could also be safely passed to other code as it would be unmodifiable.
JUSTIFICATION :
There is no way to really read a CopyOnWrite collection other than iterating over it, which dramatically limits the usefulness of these collections.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would like to see a cheap implementation of the "getSnapshot()" method in the test case below, such that the output of the given code was always consistent with the logical branches in the if statements.
Granted, the "getSnapshot()" method could be implemented by copying the current contents of _list to a new ArrayList, but the underlying array should not need to be copied. There should be a cheap method which returns, essentially, "Collections.unmodifableList(Arrays.asList(_list.array))".
ACTUAL -
If the list is modified while the doSomething() method is executing, the output will not be consistent with the logical decisions made (in some cases, an exception could be thrown).
---------- BEGIN SOURCE ----------
public class MyClass {
public final CopyOnWriteArrayList<String> _list = new CopyOnWriteArrayList<String>();
private List<String> getSnapshot() {
return _list;
}
public void doSomething() {
List<String> snap = getSnapshot();
if(snap.size() == 1) {
System.out.println("My list has one element: " + snap.get(0));
} else {
System.out.println("My list does not have one element: " + snap);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
return "new ArrayList<String>(_list)" from getSnapshot(), which is way more inneficient than it needs to be.