成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ConcurrentModificationException,iterator迭代問題[源碼分析]

junnplus / 702人閱讀

摘要:單線程的迭代過程中刪除集合元素以上代碼會出現(xiàn)如下異常從后往前看第行代碼我們在執(zhí)行代碼行時調(diào)用了這個是調(diào)用返回的對象這個對象的方法如下圖方法首先它會調(diào)用這個方法這個方法很簡單就是比較這兩個值是不是相等不相等就拋出異常如下圖這兩個值為什么會不相

單線程的Iterator迭代過程中刪除集合元素
public class TestIterator {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        list.add("6");

        Iterator it = list.iterator();
        while (it.hasNext()) {
            String next = it.next();
            if("3".equals(next)) {
                list.remove(3);
            }
            System.out.println(next);
        }


    }
}

以上代碼會出現(xiàn)如下異常

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    at java.util.ArrayList$Itr.next(ArrayList.java:851)
    at caoyan.test.TestIterator.main(TestIterator.java:22)

從后往前看:
TestIterator第22行代碼:

String next = it.next();

我們在執(zhí)行代碼22行時調(diào)用了it.next();這個it是ArrayList調(diào)用iterator()返回的對象;這個對象的next()方法如下圖:

  public E next() {
            checkForComodification();
            ...

next()方法首先它會調(diào)用checkForComodification()這個方法,這個方法很簡單,就是比較expectedModCount , modCount 這兩個值是不是相等;不相等就拋出異常;如下圖:

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

這兩個值為什么會不相等,它們各自代表什么含義呢,我們看ArrayList的iterator()方法:

    public Iterator iterator() {
        return new Itr();
    }

    /**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

Arraylist的iterator()方法,直接創(chuàng)建了一個私有的內(nèi)部類Itr的對象;expectedModCount 就是定義在這個Itr中的成員變量,而且,在初始化的時候,將modCount賦值給expectedModCount,說明在剛生成Iterator的時候這兩個值是相等的.modCount是定義在哪里呢,看下面源碼

public class ArrayList extends AbstractList
...
protected transient int modCount = 0;

modCount是AbstractList的成員變量,ArrayList繼承下來了.所以modCount代表ArrayList的實(shí)際長度.
當(dāng)我們在iterator的迭代過程中改變了ArrayList的長度,就導(dǎo)致modCount變了,而expectedModCount 沒有變,導(dǎo)致不相等報錯

可是為什么用iterator的remove方法就不報錯呢,我們看Remove方法():

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在刪除元素后,expectedModCount = modCount;重新賦值,讓這兩個值相等了.所以,remove方法不會拋出這個異常

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76300.html

相關(guān)文章

  • ConcurrentModificationException,iterator迭代問題[源碼分析]

    摘要:單線程的迭代過程中刪除集合元素以上代碼會出現(xiàn)如下異常從后往前看第行代碼我們在執(zhí)行代碼行時調(diào)用了這個是調(diào)用返回的對象這個對象的方法如下圖方法首先它會調(diào)用這個方法這個方法很簡單就是比較這兩個值是不是相等不相等就拋出異常如下圖這兩個值為什么會不相 單線程的Iterator迭代過程中刪除集合元素 public class TestIterator { public static voi...

    zhoutk 評論0 收藏0
  • ConcurrentModificationException,iterator迭代問題[源碼分析]

    摘要:單線程的迭代過程中刪除集合元素以上代碼會出現(xiàn)如下異常從后往前看第行代碼我們在執(zhí)行代碼行時調(diào)用了這個是調(diào)用返回的對象這個對象的方法如下圖方法首先它會調(diào)用這個方法這個方法很簡單就是比較這兩個值是不是相等不相等就拋出異常如下圖這兩個值為什么會不相 單線程的Iterator迭代過程中刪除集合元素 public class TestIterator { public static voi...

    aaron 評論0 收藏0
  • Java 迭代器引發(fā) ConcurrentModificationException

    摘要:迭代器智能嗎第一步,將列表中的根節(jié)點(diǎn)找出來。源碼翻開中迭代器的源碼。在迭代器對象執(zhí)行操作之前,都會執(zhí)行方法,以判斷當(dāng)前操作下是否安全。 引言 ConcurrentModificationException這個異常大家都很熟悉,當(dāng)在forEach進(jìn)行刪除時都會出現(xiàn)該異常。 如果你還不了解,請參考澍澍的博客:關(guān)于在list循環(huán)的過程中進(jìn)行刪除的處理 - 晨澍的博客 showImg(http...

    用戶83 評論0 收藏0
  • Java 迭代器引發(fā) ConcurrentModificationException

    摘要:迭代器智能嗎第一步,將列表中的根節(jié)點(diǎn)找出來。源碼翻開中迭代器的源碼。在迭代器對象執(zhí)行操作之前,都會執(zhí)行方法,以判斷當(dāng)前操作下是否安全。 引言 ConcurrentModificationException這個異常大家都很熟悉,當(dāng)在forEach進(jìn)行刪除時都會出現(xiàn)該異常。 如果你還不了解,請參考澍澍的博客:關(guān)于在list循環(huán)的過程中進(jìn)行刪除的處理 - 晨澍的博客 showImg(http...

    kumfo 評論0 收藏0
  • ArrayList 源碼詳細(xì)分析

    摘要:源碼分析構(gòu)造方法有兩個構(gòu)造方法,一個是無參,另一個需傳入初始容量值。所以我們可以把上面的代碼轉(zhuǎn)換一下,等價于下面形式這個時候,我們再去分析一下的迭代器源碼就能找出原因。原因是刪除元素后,元素計數(shù)器,而迭代器中的也等于,從而導(dǎo)致返回。 1.概述 ArrayList 是一種變長的集合類,基于定長數(shù)組實(shí)現(xiàn)。ArrayList 允許空值和重復(fù)元素,當(dāng)往 ArrayList 中添加的元素數(shù)量大于...

    W4n9Hu1 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<