What are Fail Fast Iterators in Java Collections?
Tags: corejava, interviewquestion, collections
Published: 2021-06-12 17:31:26

Signed in as @priyankanandula

Hello, <u>**Developers**</u> hope you guys are doing great :smiley:.Today I came up with an _interesting and important_ concept in `Java Collections`, as well as in `interviews`. I hope you enjoy it.

Do you know what was the issue with using the `for-loop` to iterate the Collection objects :question:

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s7aq40s6qye3tsx35jyx.png)
</br>
######Let me explain <u>this</u> to you in such case :point_down:.

-----

Let's take a look at the following code

```java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class IteratorDemo {

	
	private static void arrayListDemo() {
		List<Integer> list=new ArrayList<>();
		list.add(5);
		list.add(6);
		list.add(7);
		list.add(9);
		for(int element:list) {
			
			System.out.println("element : "+element);
			
			if(element==6) {
				
				list.remove(Integer.valueOf(7));
			}
		}
		
	}
	
	public static void main(String[] args) {
		arrayListDemo();
		
	}

}
```

####OUTPUT : 

```java
element : 5
element : 6
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
	at java.util.ArrayList$Itr.next(Unknown Source)
	at IteratorDemo.arrayListDemo(IteratorDemo.java:14)
	at IteratorDemo.main(IteratorDemo.java:27)
```
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/911g7omo8qk3hlhp9pvh.png)

It was printed **up to element 6**, after which the element in the following index is _7_, and we have put a <u>condition to remove that element</u> from the `list` if it is 7 and here it was thrown 
<mark>java.util.ConcurrentModificationException</mark>

> NOTE : However, we can do `replacement operations` such as _set method_, and this exception will never be thrown.


</br>
###Root Cause :

Internally, `for-each` statement, it invokes the **iterator function** for the _given object_ and iterates over the elements using the _instance obtained by the iterator_.

The iterator, which is internally written, generates the <mark>concurrent modification exception</mark>.


The iterator **does not allow us to make any concurrent structural changes (removing/adding)** to the _underlying ArrayList_.

Such _Iterators_ which gives a <mark>concurrent modification exception</mark> are called **_fail-fast Iterator_**.

###Solution :

The solution here is to use `Iterator interface` and to access an instance of iterator we need to invoke the _iterator_ method which is declared in the `Iterable interface`.

Collection interface already extends the `Iterable interface` and collection implementations like _ArrayList, HashSet.._ implements the `Iterator method`.

> public interface Collection<E>
extends Iterable<E>{..}

_Collection_ interface is saying that its elements can be iterated by extending the `Iterable`.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejdwr13li2ek3wt7nphs.png)

<h6>The `java.lang.Iterable` interface provides the following methods:</h6>

 <ul>
  <li><b>iterator()</b> : We can iterate the elements of Java Iterable by obtaining the _Iterator_ from it using the iterator() method.</li>
  <li>**forEach​(Consumer<? super T> action)** : Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception.</li>
  <li>**spliterator()** : The Spliterator interface, can be used for _traversing and partitioning sequences_. It's a base utility for Streams, especially parallel ones.</li>
 </ul>   

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8jmwnhkren9dpaa5uo0.png)

<h6>The  `java.util.Iterator` interface provides the following methods:</h6>

 <ul>
  <li>**boolean hasNext()** - Returns true if the iteration has more elements.</li>
  <li>**E next()** - Returns the next element in the iteration.</li>
  <li>**void remove()** - Removes from the underlying collection the last element returned by the iterator (optional operation).</li>
<li>**forEachRemaining(Consumer<? super E>action)** - Performs the given action on each of the element until and unless all the elements have been processed or unless an exception is thrown by the action.</li>
  </ul> 

---

Now, using the `Iterator interface`, we'll rewrite the code to _remove the element_.

```Java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class IteratorDemo {

	
	private static List<Integer> arrayListDemo() {
		List<Integer> list=new ArrayList<>();
		list.add(5);
		list.add(6);
		list.add(7);
		list.add(9);
		
		
		return list;
	}
	
	private static void iteratorDemo(List<Integer> list1) {
		System.out.println("\nInside iteratorDemo ... ");
				
		Iterator<Integer> iterator = list1.iterator();
		while (iterator.hasNext()) {
			int element = iterator.next();
			System.out.println("element: " + element);
			
			if (element == 9) {
				iterator.remove();
				
			}
		}
		System.out.println("List After removing the element " + list1);
		
				
	}
	
	public static void main(String[] args) {
		List<Integer> list1 = arrayListDemo();
		iteratorDemo(list1);
	}
}

```

####OUTPUT :

```java

Inside iteratorDemo ... 
element: 5
element: 6
element: 7
element: 9
List After removing the element [5, 6, 7]
```

Yo :metal: ! It doesn't throw any exceptions anymore.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y3io6qcgbjpybc8xq35x.png)

 

> NOTE : The invocation of remove method must be **preceded by the invocation of next() method** otherwise it will **throw an exception**.Because the _remove method will removes the element that was returned by the next() method_.

######For Example : Sample Code 
```java
while (iterator.hasNext()) {
			int element = iterator.next();
			System.out.println("element: " + element);
			
			if (element == 9) {
				iterator.remove();
				iterator.remove();
			}
		}
``` 
###OUTPUT
```java
Inside iteratorDemo ... 
element: 5
element: 6
element: 7
element: 9
Exception in thread "main" java.lang.IllegalStateException
	at java.util.ArrayList$Itr.remove(Unknown Source)
	at IteratorDemo.iteratorDemo(IteratorDemo.java:30)
	at IteratorDemo.main(IteratorDemo.java:40)
```

> It will throw an exception at the second remove method because it has to be preceded by next() method only. 

---

__Generally the use case of this scenario like removing during the iteration  could be that you may have retrieved a list of elements form the database  and now you want to remove some of them which meets certain criteria__.


<center>That's it for today, guys. I hope you learned something new.</center>


![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4paa61bwlu8zi5x18idz.png)


This is _priyanka nandula_ signing off...