Java iterators remove elements ConcurrentModificationException exception.

Java does not support the use of container in the iterator class iterative process, using as list.remove (obj) method to remove elements. Otherwise it will throw an exception ava.util.ConcurrentModificationException. You should remove the elements of the current iteration to use iterator.remove () method.

This is because there is a set of Java called fail-fast mechanism, that is, if multiple threads operating on the same set of content, it will produce fail-fast events that throw an exception.

For example, the code below

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Hello {

    public static void main(String[] args) {
        List<String> all=new ArrayList<String>();
        all.add("Hello");
        all.add("_");
        all.add("World!!");
        Iterator<String> iterator=all.iterator();
        while(iterator.hasNext())
        {
            String str=iterator.next();
            if("Hello".equals(str))
            {
                all.remove(str);

            }
            else
            {
                System.out.println( str+" ");
            }
        }
        System.out.println("\n删除\"_\"之后的集合当中的数据为:"+all);
    }
}

Delete the following elements will throw an exception

Here you change the contents of the original set of storage in an iterative process, so off fail-fast mechanism.

fail-fast mechanism is provided. The above code to throw exceptions, for example. View source ArrayList. Class, you can see that throws an exception for

Here modCount document is explained

The number of times this list has been structurally modified. Structural modifications are those that change the size of the list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.

Probably the number means that the list of structures are modified. Structural changes, including changing the list's size, or other iteration result may cause interference misbehaving.

expectedModCount comments to:

The modCount value that the iterator believes that the backing List should have.  If this expectation is violated, the iterator has detected concurrent modification.

Thus if a change in the structure List iterative process, i.e. using remove, or add other methods will result in different values ​​of the modCount expectedModCount, it will throw an exception.

But there is a strange phenomenon, if we use List.remove (obj) method to delete the penultimate element does not exceed an exception. Such as

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Hello {

    public static void main(String[] args) {
        List<String> all=new ArrayList<String>();
        all.add("Hello");
        all.add("_");
        all.add("World!!");
        Iterator<String> iterator=all.iterator();
        while(iterator.hasNext())
        {
            String str=iterator.next();
            if("_".equals(str))
            {
                all.remove(str);

            }
            else
            {
                System.out.println( str+" ");
            }
        }
        System.out.println("\n删除\"_\"之后的集合当中的数据为:"+all);
    }
}

Note that deleted '_' as the penultimate element in the collection. Also note that the code has, if not delete this element, the output of this element, namely else the contents inside. Results

Not to say, can not be used List.remove (obj) way, can only be deleted by iterator.remove () way, why not throw an exception here. The reason is this.

See the source ArrayList method hasNext () and next () method

size is the size of the current collection, Cursor next index element is initialized to 0

其中checkForComodification的源码为,两个变量的的解释上面也已经说了。

我们的迭代器部分代码按下面步骤执行:

all里面存储了“Hello”,"_","world!"三个元素

  1. iterator.hasNext(),
    1. cursor=0,size=3。cursor!=size,返回true,进入while内
  2. String str=iterator.next(),
    1. checkForComodification(),此时modCount=0,expectedModCount=0,因此没有抛出异常,
    2. cursor=i+1,即cursor=1
    3. return elementData[lastRet=i],str='Hello'
  3. '_'.equals(str)为False,输出Hello
  4. iterator.hasNext(),
    1. cursor=1,size=3。cursor!=size,返回true,进入while内
  5. String str=iterator.next(),
    1. checkForComodification(),此时modCount=0,expectedModCount=0,因此没有抛出异常,
    2. cursor=i+1,即cursor=2
    3. return elementData[lastRet=i],str='_'
  6. **'_'.equals(str)为Ture,**
    1. all.remove(str)
    2. modCount=1,因为改变了List的结构,因此modCount+1。
  7. iterator.hasNext(),
    1. cursor=2,size=2。cursor!=size,返回False,退出

可以看到,在这里就已经推出while循环了。不会在执行checkForComodification()方法,判断List结构有没有改变。

结论:因此只要对倒数第二个元素执行remove()方法,虽然会改变集合结构,但是因为也同时改变了集合size,使size与cursor的大小一样,就会直接循环,不会报异常。

Guess you like

Origin www.cnblogs.com/lolybj/p/10982875.html