1 public void testIterRemove() { 2 List l1 = new ArrayList(Arrays.asList(1, 2, 3, 4, 5)); 3 Iterator<Integer> iterator = l1.iterator(); 4 System.out.println("before=" + l1); 5 while (iterator.hasNext()) { 6 iterator.next(); 7 iterator.remove(); 8 } 9 System.out.println("after=" + l1);10 }11 /*12 before=[1, 2, 3, 4, 5]13 after=[]14 */
Correct example of removing elements from a time-frame
The key part of the code is:
Iterator. Next ();
And
Iterator. Remove ();
Both are indispensable. Of course, hasnext () must be called before calling next () to ensure that there is no cross-border.
Simply Analyze the code of the two methods to get the answer:
First, let's take a look at the remove () method. Why can't hasnext () + remove () be used:
1 public void remove() { 2 if (lastRet < 0) 3 throw new IllegalStateException(); 4 checkForComodification(); 5 6 try { 7 ArrayList.this.remove(lastRet); 8 cursor = lastRet; 9 lastRet = -1;10 expectedModCount = modCount;11 } catch (IndexOutOfBoundsException ex) {12 throw new ConcurrentModificationException();13 }14 }
Arraylist # itr. Remove ()
Because the Code uses the attribute lastret (lastreturn index) to control the exception, check the instance initialization Statement of arraylist # itr. The initial value of lastret is-1. If you call remove () separately, an error is returned.
Let's look at the next () method to find the answer:
1 public E next() { 2 checkForComodification(); 3 int i = cursor; 4 if (i >= size) 5 throw new NoSuchElementException(); 6 Object[] elementData = ArrayList.this.elementData; 7 if (i >= elementData.length) 8 throw new ConcurrentModificationException(); 9 cursor = i + 1;10 return (E) elementData[lastRet = i];11 }
Arraylist # itr. Next ()
In the method, first record the cursor to variable I, and assign the I knowledge to lastret before returning the result to complete lastret update. The method return value is not the scope to be considered this time.
Let's look back at the remove () method. With lastret, You can reset the cursor. Arraylist # Remove () is called in the method. This method re-adjusts the position of the array element, if the deleted element is not at the last position (nummoved = 0 indicates that the deleted element is the last element), the element following the index will be moved forward, finally, remove the old element from elementdata [-- size] = NULL to help GC.
Summary:
You must call next () to update the value of lastret before you can pass the first check on lastret in remove. Therefore, when traversing the list, you need to use the following code together:
while( it.hasNext() ) { it.next(); it.remove();}
[Brick-moving series] how to safely delete a set element when traversing a list