<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試官問:List如何一邊遍歷,一邊刪除?

          共 6087字,需瀏覽 13分鐘

           ·

          2020-06-13 23:22


          來源:https://urlify.cn/ji6bmy



          這是最近面試時(shí)被問到的1道面試題,本篇博客對此問題進(jìn)行總結(jié)分享。

          1. 新手常犯的錯(cuò)誤

          可能很多新手(包括當(dāng)年的我,哈哈)第一時(shí)間想到的寫法是下面這樣的:

          public static void main(String[] args{
              List  platformList =  new ArrayList<>();
              platformList. add( "博客園");
              platformList. add( "CSDN");
              platformList. add( "掘金");

               for (String platform : platformList) {
                   if (platform. equals( "博客園")) {
                      platformList. remove(platform);
                  }
              }

              System. out.println(platformList);
          }

          然后滿懷信心的去運(yùn)行,結(jié)果竟然拋java.util.ConcurrentModificationException異常了,翻譯成中文就是:并發(fā)修改異常。

          491d51b32e54fb68f02ceeb6af5385fd.webp

          是不是很懵,心想這是為什么呢?

          讓我們首先看下上面這段代碼生成的字節(jié)碼,如下所示:

          22919d1f21c686b2b66a62930878e557.webp

          由此可以看出,foreach循環(huán)在實(shí)際執(zhí)行時(shí),其實(shí)使用的是Iterator,使用的核心方法是hasnext()和next()。

          然后再來看下ArrayList類的Iterator是如何實(shí)現(xiàn)的呢?

          4ae34e7679957384b7fb9032557f5dda.webp

          可以看出,調(diào)用next()方法獲取下一個(gè)元素時(shí),第一行代碼就是調(diào)用了checkForComodification();,而該方法的核心邏輯就是比較modCount和expectedModCount這2個(gè)變量的值。

          在上面的例子中,剛開始modCount和expectedModCount的值都為3,所以第1次獲取元素"博客園"是沒問題的,但是當(dāng)執(zhí)行完下面這行代碼時(shí):

          platformList.remove(platform);

          modCount的值就被修改成了4。

          4fde0b095d9f26027c7c9d89300f877d.webp

          所以在第2次獲取元素時(shí),modCount和expectedModCount的值就不相等了,所以拋出了java.util.ConcurrentModificationException異常。

          4c5c6cb6f79fda4ff16c2e046eb1cdee.webp

          既然不能使用foreach來實(shí)現(xiàn),那么我們該如何實(shí)現(xiàn)呢?

          主要有以下3種方法:

          • 使用Iterator的remove()方法

          • 使用for循環(huán)正序遍歷

          • 使用for循環(huán)倒序遍歷

          接下來一一講解。

          2. 使用Iterator的remove()方法

          使用Iterator的remove()方法的實(shí)現(xiàn)方式如下所示:

          public static void main(String[] args{
              List  platformList =  new ArrayList<>();
              platformList. add( "博客園");
              platformList. add( "CSDN");
              platformList. add( "掘金");

              Iterator  iterator = platformList.iterator();
               while (iterator.hasNext()) {
                  String platform = iterator.next();
                   if (platform. equals( "博客園")) {
                      iterator. remove();
                  }
              }

              System. out.println(platformList);
          }

          輸出結(jié)果為:

          [CSDN, 掘金]

          為什么使用iterator.remove();就可以呢?

          讓我們看下它的源碼:

          9de6a6577f886565de6a34a73d1e5b92.webp

          可以看出,每次刪除一個(gè)元素,都會(huì)將modCount的值重新賦值給expectedModCount,這樣2個(gè)變量就相等了,不會(huì)觸發(fā)java.util.ConcurrentModificationException異常。更多面試題,歡迎關(guān)注公眾號 Java面試題精選

          3. 使用for循環(huán)正序遍歷

          使用for循環(huán)正序遍歷的實(shí)現(xiàn)方式如下所示:

          public static void main(String[] args{
              List  platformList =  new ArrayList<>();
              platformList. add( "博客園");
              platformList. add( "CSDN");
              platformList. add( "掘金");

               for ( int i =  0; i < platformList.size(); i++) {
                  String item = platformList. get(i);

                   if (item. equals( "博客園")) {
                      platformList. remove(i);
                      i = i -  1;
                  }
              }

              System. out.println(platformList);
          }

          這種實(shí)現(xiàn)方式比較好理解,就是通過數(shù)組的下標(biāo)來刪除,不過有個(gè)注意事項(xiàng)就是刪除元素后,要修正下下標(biāo)的值:

          i = i - 1;

          為什么要修正下標(biāo)的值呢?

          因?yàn)閯傞_始元素的下標(biāo)是這樣的:

          3d90e4c86c5c0544c77e8f94adad97ba.webp

          第1次循環(huán)將元素"博客園"刪除后,元素的下標(biāo)變成了下面這樣:

          fd73c5bf78cc5c1844839363e2ba9dba.webp

          第2次循環(huán)時(shí)i的值為1,也就是取到了元素”掘金“,這樣就導(dǎo)致元素"CSDN"被跳過檢查了,所以刪除完元素后,我們要修正下下標(biāo),這也是上面代碼中i = i - 1;的用途。更多面試問題可以關(guān)注微信訂閱號碼匠筆記回復(fù)面試獲取

          4. 使用for循環(huán)倒序遍歷

          使用for循環(huán)倒序遍歷的實(shí)現(xiàn)方式如下所示:

          public static void main(String[] args{
              List  platformList =  new ArrayList<>();
              platformList. add( "博客園");
              platformList. add( "CSDN");
              platformList. add( "掘金");

               for ( int i = platformList.size() -  1; i >=  0; i--) {
                  String item = platformList. get(i);

                   if (item. equals( "掘金")) {
                      platformList. remove(i);
                  }
              }

              System. out.println(platformList);
          }

          這種實(shí)現(xiàn)方式和使用for循環(huán)正序遍歷類似,不過不用再修正下標(biāo),因?yàn)閯傞_始元素的下標(biāo)是這樣的:

          3d90e4c86c5c0544c77e8f94adad97ba.webp

          第1次循環(huán)將元素"掘金"刪除后,元素的下標(biāo)變成了下面這樣:

          2976e529cc90324f2016467742da4d43.webp

          第2次循環(huán)時(shí)i的值為1,也就是取到了元素”CSDN“,不會(huì)導(dǎo)致跳過元素,所以不需要修正下標(biāo)。

          5. 參考

          https://blog.csdn.net/zjwcdd/article/details/51513879
          https://blog.csdn.net/wangjun5159/article/details/61415358


          8adcd0676dda28a11980cd99791c0070.webp
          
           

          文末福利

          分享一套Springboot開發(fā)的博客系統(tǒng)源碼,為了讓更多的Java讀者能詳細(xì)理解這個(gè)項(xiàng)目,作者把開發(fā)這個(gè)項(xiàng)目過程寫成了文檔。

          從0到1一步一步帶你從搭建項(xiàng)目框架,各種細(xì)節(jié)調(diào)整,以及如何開發(fā)各個(gè)模塊的功能,比如即時(shí)通知,群聊,分布式實(shí)時(shí)搜索等功能,一共寫了10+篇詳細(xì)的開發(fā)設(shè)計(jì)文檔,一步一步,一行一行代碼,讓你了解整個(gè)開發(fā)項(xiàng)目的過程,理解項(xiàng)目作者開發(fā)過程中的所有思考.

          5c0b5d1f89e9319d6c36e31e532d20ea.webp

          另外,長達(dá)17小時(shí)的eblog完整講解視頻已在上線啦,非常詳細(xì),一起來學(xué)eblog。

          27708874f0af979fe61242f174528220.webp

          如何獲取項(xiàng)目地址與詳細(xì)的開發(fā)文檔?

          我把它放在我的Java開發(fā)寶典里了,大家掃一下下面的二維碼,關(guān)注后回復(fù)關(guān)鍵字:eblog,即可獲取項(xiàng)目,以及作者的詳細(xì)開發(fā)文檔、以及完整項(xiàng)目講解視頻!無任何套路!

          掃描上面二維碼,回復(fù)關(guān)鍵字:eblog


          希望大家拿去好好學(xué)習(xí),如果覺得不錯(cuò),也可以把文章分享給其他小伙伴,一起學(xué)習(xí)!


          點(diǎn)贊是最大的支持 bbc3293598cfae813f49cb79292237ec.webp

          瀏覽 30
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  91性爱网站 | 99思思| 免费在线观看视频黄 | 亚洲.www | 五月亭亭六月丁香 |