Remove operation with CopyOnWriteArrayList

In this article, we will discuss what happens when element is removed from CopyOnWriteArrayList and ArrayList while iterating using Iterator i.e.;

  • remove() operation with CopyOnWriteArrayList; while iterating using Iterator
  • remove() operation with ArrayList; while iterating using Iterator

 

1. CopyOnWriteArrayList:

  • Though, CopyOnWriteArrayList is very good choice over ArrayList while working in a multi-threaded environment
  • but there are certain limitation too
  • If we try to remove any element while iterating using Iterator;
  • then program fails and compiler throws ConcurrentModificationException

RemoveWhileIteratingCopyOnWriteArrayList.java

package in.bench.resources.concurrent.collection;

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

public class RemoveWhileIteratingCopyOnWriteArrayList {

	public static void main(String[] args) {

		// creating CopyOnWriteArrayList of type String
		CopyOnWriteArrayList<String> cowalStars = 
				new CopyOnWriteArrayList<>();

		// adding elements to CopyOnWriteArrayList
		cowalStars.add("Super Star");
		cowalStars.add("Ultimate Star");
		cowalStars.add("Rock Star");
		cowalStars.add("Little Star");

		System.out.println("Iterating using enhanced for-loop:\n");

		// iterating CopyOnWriteArrayList using enhanced for-loop
		for(String star : cowalStars) {
			System.out.println(star);
		}
		System.out.println("\n1st: Iteration of COWAL "
				+ "completed... !!\n\n");

		System.out.println("\n\n2nd: Iterating & removing:\n");

		// iterating CopyOnWriteArrayList using Iterator
		Iterator<String> itr = cowalStars.iterator();
		while(itr.hasNext()){

			String star = itr.next();

			if(star.contains("Super")){
				itr.remove();
			}
			else{
				System.out.println(star);
			}
		}
	}
}

Output:

Iterating using enhanced for-loop:

Super Star
Ultimate Star
Rock Star
Little Star

1st: Iteration of COWAL completed... !!




2nd: Iterating & removing:

Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.concurrent.CopyOnWriteArrayList$COWIterator
                          .remove(CopyOnWriteArrayList.java:1040)
	at in.bench.resources.concurrent.collection
                        .RemoveWhileIteratingCopyOnWriteArrayList
          .main(RemoveWhileIteratingCopyOnWriteArrayList.java:36)

Explanation:

  • 1st time, while iterating through CopyOnWriteArrayList contents using enhanced for-loop, all elements are printed to console as per insertion order (keep in mind, actually we haven’t done anything here like remove, etc)
  • 2nd time, when we tried to remove element after comparison while iterating using Iterator à program fails as compiler throws UnsupportedOperationException

 

ArrayList v/s CopyOnWriteArrayList :

  • But when same program is executed replacing CopyOnWriteArrayList by ArrayList,
  • then program runs without any error
  • there is no compile-time error

 

2. ArrayList:

  • It is very safe to remove elements from ArrayList while iterating using Iterator
  • compiler doesn’t throws any runtime-exception like UnsupportedOperationException

 RemoveWhileIteratingArrayList.java

package in.bench.resources.concurrent.collection;

import java.util.ArrayList;
import java.util.Iterator;

public class RemoveWhileIteratingArrayList {

	public static void main(String[] args) {

		// creating ArrayList of type String
		ArrayList<String> cowalStars = new ArrayList<>();

		// adding elements to ArrayList
		cowalStars.add("Super Star");
		cowalStars.add("Ultimate Star");
		cowalStars.add("Rock Star");
		cowalStars.add("Little Star");

		System.out.println("Iterating using enhanced for-loop:\n");

		// iterating ArrayList using enhanced for-loop
		for(String star : cowalStars) {
			System.out.println(star);
		}
		System.out.println("\n1st: Iteration of AL completed... !!\n\n");

		System.out.println("\n\n2nd: Iterating & removing:\n");

		// iterating ArrayList using Iterator
		Iterator<String> itr = cowalStars.iterator();
		while(itr.hasNext()){

			String star = itr.next();

			if(star.contains("Super")){
				itr.remove();
			}
			else{
				System.out.println(star);
			}
		}
	}
}

Output:

Iterating using enhanced for-loop:

Super Star
Ultimate Star
Rock Star
Little Star

1st: Iteration of AL completed... !!




2nd: Iterating & removing:

Ultimate Star
Rock Star
Little Star

Explanation:

  • 1st time, while iterating through ArrayList contents using enhanced for-loop, all elements are printed to console as per insertion order (keep in mind, actually we haven’t done anything here like remove, etc)
  • 2nd time, when we tried to remove element after comparison while iterating using Iterator à program doesn’t fails and again all elements are printed as per insertion order
  • But, leaving out removed element
  • In this case, Super star because we have kept check for this only using if-else condition

 

References:

 

Happy Coding !!
Happy Learning !!

CopyOnWriteArrayList v/s ArrayList
CopyOnWriteArrayList with Read and Update operations simultaneously