Iterator的remove方法实际上是如何删除一个对象的

我们都知道,在迭代它时从集合中删除对象的最安全的“且可能只是安全的”方法是首先检索Iterator ,执行循环并在需要时删除;

 Iterator iter=Collection.iterator(); while(iter.hasNext()){ Object o=iter.next() if(o.equals(what i'm looking for)){ iter.remove(); } } 

我想要了解的,并且遗憾的是没有找到深入的技术解释,是如何执行此删除,
如果:

 for(Object o:myCollection().getObjects()){ if(o.equals(what i'm looking for)){ myCollection.remove(o); } } 

将抛出一个ConcurrentModificationException ,“技术术语” Iterator.remove()做什么? 它是否删除了对象,打破了循环并重新启动循环?

我在官方文档中看到:

“删除当前元素。如果尝试调用remove()之前没有调用next(),则抛出IllegalStateException 。”

部分“删除当前元素”,让我想到在“常规”循环中发生的完全相同的情况=>(执行相等性测试并在需要时删除),但为什么Iterator循环ConcurrentModification安全?

Iterator如何删除元素取决于它的实现,对于不同的集合可能会有所不同。 肯定它不会破坏你所处的循环。我刚刚看了如何实现ArrayList迭代器,这里是代码:

 public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } 

因此,它检查并发修改,使用公共ArrayList remove方法删除元素,并增加列表修改的计数器,以便在下一次迭代时不会抛出ConcurrentModificationException。

你在迭代它时不能修改列表的原因是因为迭代器必须知道要为hasNext()和next()返回什么。

如何完成这是特定于实现,但你可以看看ArrayList / AbstractList / LinkedList等的源代码。

另请注意,在某些情况下,您可以使用此类代码作为替代方法:

 List copyList = new ArrayList<>(origList); for (Foo foo : copyList){ if (condition){ origList.remove(foo); } } 

但是这段代码可能会运行得稍慢,因为必须复制集合(仅浅拷贝),并且必须搜索要删除的元素。

另请注意,如果您直接使用迭代器,建议使用for循环而不是while循环,因为这会限制变量的范围:

 for (Iterator iterator = myCollection.iterator(); iterator.hasNext();){ ... }