Reputation: 5637
see the below code
import java.util.Enumeration;
import java.util.Vector;
public class Modification_On_Eumeration {
public static void main(String[] args) {
Vector<Integer> vector = new Vector<Integer>();
vector.add(1);
vector.add(2);
System.out.println(vector);
Enumeration<Integer> enumeration = vector.elements();
while (enumeration.hasMoreElements()) {
Integer integer = (Integer) enumeration.nextElement();
System.out.print(integer);
}
System.out.println();
System.out.println("first loop finished");
vector.add(3);
while (enumeration.hasMoreElements()) {
Integer integer1 = (Integer) enumeration.nextElement();
System.out.println(integer1);
}
}
}
the above code is working fine and the output is:
[1, 2]
12
first loop finished
3
now see the below code:
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;
public class Fail_Safe_Iterator {
public static void main(String[] args) {
CopyOnWriteArrayList<Integer> copyOnWriteArrayList=new CopyOnWriteArrayList<Integer>();
copyOnWriteArrayList.add(6);
copyOnWriteArrayList.add(2);
System.out.println(copyOnWriteArrayList);
Iterator<Integer> iterator=copyOnWriteArrayList.iterator();
while (iterator.hasNext()) {
Integer integer = (Integer) iterator.next();
System.out.println(integer);
}
System.out.println("first loop finished");
copyOnWriteArrayList.add(5);
while (iterator.hasNext()) {
Integer integer = (Integer) iterator.next();
System.out.println(integer);//why not printing 5
}
}
}
the output is:
[6, 2]
6
2
first loop finished
I am learning java..my doubt is in the fist example after adding 3,I am able to retrive and print it.but in the second example after adding 5 I am unable to retrive and print it.what is the reason ? is it due to iterator fail safe behaviour ? or is it one of the difference beween enumeration and iterator? help me....
Upvotes: 1
Views: 389
Reputation: 94469
The CopyOnWriteArrayList
creates a new Iterator
based upon the current state of the underlying array that backs the list.
Java Source
public ListIterator<E> iterator() {
return new COWIterator<E>(getArray(), 0);
}
This iterator does not contain the element added after its creation because the CopyOnWriteArrayList
performs mutative operations (add, set, and so on) by making a fresh copy of the underlying array. Therefore, when you create an iterator it is reflection of the underlying array at that instant.
Fix
System.out.println("first loop finished");
copyOnWriteArrayList.add(5);
//get the new iterator after adding
iterator = copyOnWriteArrayList.iterator();
while (iterator.hasNext()) {
Integer integer = (Integer) iterator.next();
System.out.println(integer);//why not printing 5
}
Upvotes: 5
Reputation: 195099
The problem is you used CopyOnWriteArrayList
class:
from java doc of CopyOnWriteArrayList:
The "snapshot" style iterator method uses a reference to the state of the array at the point that the iterator was created. This array never changes during the lifetime of the iterator, so interference is impossible and the iterator is guaranteed not to throw ConcurrentModificationException. The iterator will not reflect additions, removals, or changes to the list since the iterator was created. Element-changing operations on iterators themselves (remove, set, and add) are not supported. These methods throw UnsupportedOperationException
Upvotes: 0
Reputation: 121740
The difference is that Iterator
has a .remove()
operation whereas an Enumeration
doesn't.
Also, we are in 2014, so don't use Vector
nor Enumeration
; they are obsolete and only legacy APIs still use them.
As to why your program behaves this way, this is due to the "copy on write" of CopyOnWriteArrayList
: the iterator is created with the current list contents; if you modify that list after you have created your iterator, you won't see the modifications.
Upvotes: 1