久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

為什么不能在foreach循環(huán)進(jìn)行remove/add操作,?

 昵稱63565800 2019-04-25

廢話少說,,直接上測試代碼:

public class ForeachTest {
    public static void main(String[] args){
        List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("hello1");
        list.add("hello2");
//        for (int i = 0; i < list.size(); i++) {
        for(String s:list){
            list.remove("hello");
            System.out.println(s);
        }
    }
}

結(jié)果如下: 

 

 然后換一種遍歷方式:

public class ForeachTest {
    public static void main(String[] args){
        List<String> list = new ArrayList<>();
        list.add("hello");
        list.add("hello1");
        list.add("hello2");
        for (int i = 0; i < list.size(); i++) {
//        for(String s:list){
            list.remove("hello");
            System.out.println(list.get(i));
        }
    }
}

 結(jié)果如下:


以上是兩種測試的對比現(xiàn)象(結(jié)果),那么既然有了結(jié)果接下來就要分析原因了,。

控制臺拋異常首先定位異常拋出的地方,,通過查看ArrayList源碼可以得知異常觸發(fā)點(diǎn)為:

可知,異常的原因是因為modCount != expectedModCount導(dǎo)致的,。

接下來就是分別查看這兩個參數(shù)的含義和可以修改他們的操作了,。

  • modCount:是AbstractList的一個成員變量:
    protected transient int modCount = 0;

    但是ArrayList是繼承AbstractList的,這里modCount的修飾符是protected,,所以是可以被subclass繼承的,。
    繼續(xù)查看源碼,對modCount的英文解釋為:

    The number of times this list has been <i>structurally modified</i>.翻譯:記錄該list結(jié)構(gòu)被修改的次數(shù),。
    
    查看源碼中該變量的修改情況,,發(fā)現(xiàn)就是在add/remove的時候,修改了modeCount的值,。
  • expectedModCount:是ArrayList的一個內(nèi)部類的成員變量

    說明:這里我們知道增強(qiáng)for底層的實現(xiàn)還是通過Iterator實現(xiàn)的,,所以這里就不難理解為什么出現(xiàn)在這個地方了。

  • 在Iterator遍歷開始就設(shè)置了兩個參數(shù)相等,,那么是什么情況導(dǎo)致了兩個參數(shù)不等呢,?
    前面我們知道在對集合進(jìn)行add和remove的時候會修改modCount的值,而我們整個iterator都沒有修改expectedModCount的值,,所以在我們使用增強(qiáng)for遍歷的時候,,如果進(jìn)行add/remove的操作,就會導(dǎo)致兩個參數(shù)不等,,然后拋出異常,。

fail-fast機(jī)制:以上我們是從代碼層面分析出了,為什么拋出異常,,但是我們其實還不是很清楚為什么要這么設(shè)計,。其實這是Java的fail-fast 機(jī)制,即快速失敗機(jī)制,,是java集合(Collection)中的一種錯誤檢測機(jī)制。

詳細(xì)解釋如下:


上面我們基本了解了異常原因和原理,,接下來的問題就是我們該如何在業(yè)務(wù)中處理這種情況呢,?

  1. 第一種方式:我們使用一般的for循環(huán)即可;
  2. 第二種方式:我們使用Iterator自帶的remove方法進(jìn)行操作,,因為自帶的方法是同步了modCount和expecteModCount的,;
  3. 第三種方式:使用Java8中的filter;
  4. 第四種方式:新建一個集合來裝過濾后的數(shù)據(jù)(這種方式比較消耗內(nèi)存,,不推薦使用);
  5. 第N種方式:已經(jīng)知道原因和原理了,,其實處理方式就很靈活了,,可以自己想想其他方式了,哈哈?。,。?/li>

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多