Unsuccessful iterator implementation

There are similar questions, but not exactly what I want to ask. I want to ask how the Iterator checks the modification.

This link indicates that its implementation is present in the AbstractList class, where an int variable modCount is defined, which provides the number of times the list has been resized. This value is used in each subsequent () call to check for any changes to the checkForComodification () function.

But I could not understand it. If the value is checked only after each next call, then if I do a delete followed by the same call, the size will not change, and modCount will also not change. But deleting and adding to the same iteration of the loop also throws an exception.

+6
source share
2 answers

If you look at the code for implementing Collection , select ArrayList ; we have the modCount variable declared in AbstractList :

 protected transient int modCount = 0; 

And then in each modifying method (for example, remove ) for ArrayList we have

 public E remove(int index) { rangeCheck(index); modCount++; //.... 

So modCount only increasing; it has never declined.

In Iterator we have:

 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } 

Where expectedModCount is the modCount snapshot taken when creating the Iterator .

So, if there is any modification to the underlying List while the same instance of Iterator used, then a ConcurrentModificationException will be thrown.

I believe that there is an angular case where you have performed enough modifications, then int overflow and return to its original value again - this would be a rather large number or modifications; 2 32 to be exact.

+8
source

modCount always increases when the list changes (hence the number of mods), so it should also increase when deleted. Thus, this would increase when calling remove and add.

As Boris Spider said, there is an angular case when modCount overflows, you can see this by doing:

 List<Integer> nums = new ArrayList<>(); for(int i = 0; i < 10; i++) nums.add(i); for(int n : nums) { System.out.println(n); for(int i = -1; i < Integer.MAX_VALUE; i++) { nums.add(i); nums.remove(nums.size() - 1); } } 

Which will (slowly) print from 0 to 9 without any exceptions.

+6
source

Source: https://habr.com/ru/post/955528/


All Articles