Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove elements from CopyOnWriteArrayList

I am getting an exception when I try to remove elements from CopyOnWriteArrayList using an iterator. I have noticed that it is documented

Element-changing operations on iterators themselves (remove, set, and add) are not supported. These methods throw UnsupportedOperationException.

(from http://download.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html)

Now, surprisingly i can iterate it with foreach and use the remove() function . But then I get the famous bug - when trying to remove an item from a list using a for loop - you skip the element next to the removed element. any suggestions then?

like image 641
Bick Avatar asked Apr 10 '11 14:04

Bick


People also ask

Can we remove element from CopyOnWriteArrayList?

The remove(int index) method of CopyOnArrayList in Java is used to remove the element at the specified position in the list. Parameters: This method accepts a mandatory parameter index which specifies the position of the element. Return Type: This method returns the list after deleting the specified element.

Is CopyOnWriteArrayList thread safe?

CopyOnWriteArrayList is a thread-safe variant of ArrayList where operations which can change the ArrayList (add, update, set methods) creates a clone of the underlying array. CopyOnWriteArrayList is to be used in a Thread based environment where read operations are very frequent and update operations are rare.

What is difference between ArrayList and CopyOnWriteArrayList?

CopyOnWriteArrayList is synchronized. ArrayList is not thread safe. CopyOnWriteArrayList is thread safe. ArrayList iterator is fail-fast and ArrayList throws ConcurrentModificationException if concurrent modification happens during iteration.

What is the use of CopyOnWriteArrayList?

Creates a list containing the elements of the specified collection, in the order they are returned by the collection's iterator.


2 Answers

Since this is a CopyOnWriteArrayList it is totally safe to remove elements while iterating with forEach. No need for fancy algorithms.

list.forEach(e -> {
    if (shouldRemove(e))
        list.remove(e);
});

EDIT: Well of course that works if you want to delete elements by reference, not by position.

like image 65
Hooman Valibeigi Avatar answered Sep 16 '22 12:09

Hooman Valibeigi


If you want to delete all use just clear(). If you want to keep elements put them in a temporary ArrayList and get them back from there.

List<Object> tKeepThese= new ArrayList<>();
for(ListIterator<Object> tIter = theCopyOnWriteArrayList; tIter.hasNext();)
{
    tObject = tIter.next();
    if(condition to keep element)
        tKeepThese.add(tObject);
}
theCopyOnWriteArrayList.clear();
theCopyOnWriteArrayList.addAll(tKeepThese);
like image 42
The incredible Jan Avatar answered Sep 19 '22 12:09

The incredible Jan