Created
May 7, 2015 03:13
Revisions
-
pyq created this gist
May 7, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,112 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; /** * Created by pyq on 5/6/15. */ /* 1. how does hasNext() work public boolean hasNext() { return cursor != size; } size: the number of elements it contains cursor: index of next element to return 2. how does next() work public E next() { checkForComodification(); .. returns the next element in the iteration } 3. how does checkForComodification() work final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } modCount: The number of times this list has been structurally modified. 4. iterator.remove(); // increase modCount and also update expectedModCount, make it equal to modCount. 5. collection.remove(value); // only increase modCount */ public class IteratorRemove { public static void removeWithTwo() { Collection<String> collection = new ArrayList<String>(2); collection.add("one"); collection.add("two"); System.out.printf("%d%n", collection.size()); // 2 for (String value : collection) { System.out.printf("%s%n", collection.remove(value)); // true } System.out.printf("%d%n", collection.size()); // 1 } /* this for each loop just like following code for (Iterator<String> iterator = collection.iterator(); iterator.hasNext();) { String value = iterator.next(); System.out.printf("%s%n", collection.remove(value)); } after removed index 0 element(cursor 0), then increased the cursor by 1, now cursor is 1. (at the same time, size will decreased by 1, size is from 2 to 1) Because cursor == size. hasNext return false, (jump out of loop) We don't invoke next() after we removed the element "one", so we will not get ConcurrentModificationException and the collection.size() will just return size = 1. */ public static void removeWithThree() { Collection<String> collection = new ArrayList<String>(2); collection.add("one"); collection.add("two"); collection.add("three"); System.out.printf("%d%n", collection.size()); // 3 for (String value : collection) { System.out.printf("%s%n", collection.remove(value)); // true then throws ConcurrentModificationException } System.out.printf("%d%n", collection.size()); } // removeWithThree is just like removeWithThreeII /* with three element after we removed "one", cursor is 1, size is 2 (3 - 1), the hasNext will return true, (modCount++) now we jump to the next iteration of the loop(trying to remove "two"), but when invoke next(). we will throw ConcurrentModificationException (since modCount != expectedModCount) modeCount now is equal to expectedModCount + 1 */ public static void removeWithThreeII() { Collection<String> collection = new ArrayList<String>(2); collection.add("one"); collection.add("two"); collection.add("three"); System.out.printf("%d%n", collection.size()); // 3 for (Iterator<String> itr = collection.iterator(); itr.hasNext();) { String value = itr.next(); System.out.printf("%s%n", collection.remove(value)); // true then throws ConcurrentModificationException } System.out.printf("%d%n", collection.size()); } //Iterator.remove is the only safe way to modify a collection during iteration // when execute iterator.remove(); we will have modCount++ and expectedModCount = modCount. These two variables are always the same. public static void correctRemoveWithThree() { Collection<String> collection = new ArrayList<String>(2); collection.add("one"); collection.add("two"); collection.add("three"); System.out.printf("%d%n", collection.size()); // 3 Iterator<String> iterator = collection.iterator(); while (iterator.hasNext()) { iterator.next(); iterator.remove(); } System.out.printf("%d%n", collection.size()); } public static void main(String[] args) { //removeWithTwo(); //removeWithThree(); //removeWithThreeII(); correctRemoveWithThree(); } }