Java ArrayList vs CopyOnWriteArrayList and Exploring Iterator

ArrayList is one of the basic implementations of List interface and it’s part of Java Collections Framework. We can use iterator to traverse through ArrayList elements.

Let’s check a sample program of ArrayList.

package com.journaldev.collections;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class ConcurrentListExample {

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        
        // get the iterator
        Iterator<String> it = list.iterator();
        
        //manipulate list while iterating
        while(it.hasNext()){
            System.out.println("list is:"+list);
            String str = it.next();
            System.out.println(str);
            if(str.equals("2"))list.remove("5");
            if(str.equals("3"))list.add("3 found");
            //below code don't throw ConcurrentModificationException
            //because it doesn't change modCount variable of list
            if(str.equals("4")) list.set(1, "4");
        }
    }

}

When we run above program, we get java.util.ConcurrentModificationException as soon as the ArrayList is modified. It happens because ArrayList iterator is fail-fast by design. What it means is that once the iterator is created, if the ArrayList is modified, it throws ConcurrentModificationException.

If you check the console log, you will notice that exception is thrown by Iterator next() method. If you will look into the ArrayList source code, following method is called everytime we invoke next() on iterator that throws exception.

        final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

Here modCount is the ArrayList variable that holds the modification count and every time we use add, remove or trimToSize method, it increments. expectedModCount is the iterator variable that is initialized when we create iterator with same value as modCount. This explains why we don’t get exception if we use set method to replace any existing element.

So basically iterator throws ConcurrentModificationException if list size is changed.

Sometimes we want to add or remove elements from the list if we find some specific element, in that case we should use Concurrent Collection class – CopyOnWriteArrayList. This is a thread-safe variant of java.util.ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array.

CopyOnWriteArrayList introduces extra overload to the processing but it’s very effective when number of modifications are minimal compared to number of traversal operations.

If we change the implementation to CopyOnWriteArrayList, then we don’t get any exception and below is the output produced.

list is:[1, 2, 3, 4, 5]
1
list is:[1, 2, 3, 4, 5]
2
list is:[1, 2, 3, 4]
3
list is:[1, 2, 3, 4, 3 found]
4
list is:[1, 4, 3, 4, 3 found]
5

Notice that it allows the modification of list, but it doesn’t change the iterator and we get same elements as it was on original list.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Current ye@r *

Subscribe to JournalDev Newsletter
Get the FREE access to Monthly Newsletter and Free PDF eBooks
*No Spam Guaranteed. By entering your email address, you agree also subscribing to our newsletter.
Oops! - Something went wrong.
Close
Today's Special: Java Persistence API PDF eBook Free Download Now
Exclusive Offer: Citrix™ Whitepaper on Denial of Service Attack Download Now