The code is pretty simple:
List lst1 = new ArrayList(){{add("1");}};
Iterator it = lst1.iterator();
System.out.println(it.hasNext());
it.next();
System.out.println(it.hasNext());
lst1.remove(0);
System.out.println(it.hasNext());
I know that you should never remove from a collection while iterating through its iterator, please don’t tell me that.
Instead, please give me a sane explanation why would a remove() operation change the value returned by hasNext() from false to true:
$ /usr/lib/jvm/sun-jdk-1.6/bin/java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)
true
false
true
hasNext() API documentation clearly states that it should return true ONLY if there are more elements in the iterator, and calling next() returns an element. The output proves that it’s not the case with SUN JDK 1.6
IBM JDK doesn’t do that, hasNext returns false after remove() gets called:
$ /usr/lib/jvm/ibm-jdk-bin-1.6/bin/java -version
java version "1.6.0"
Java(TM) SE Runtime Environment (build pxi3260sr9fp2-20110625_01(SR9 FP2))
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux x86-32 jvmxi3260sr9-20110624_85526 (JIT enabled, AOT enabled)
true
false
false
Is there a bug in Sun/Oracle hasNext() method? Or, is there a bug in IBM hasNext() method? Or, should I just not bother with all that?
From Iterator.remove():
“The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.”
So it is unspecified, meaning that NOTHING is a bug. It could format your harddisk in this case, and still not be incorrect.