日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java list 删除元素_Java面试题:List如何一边遍历,一边删除?

發布時間:2023/12/19 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java list 删除元素_Java面试题:List如何一边遍历,一边删除? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是最近面試時被問到的1道面試題,本篇文章對此問題進行總結分享。

面試清單(Java崗):Java+JVM+數據庫+算法+Spring+中間件+設計模式?shimo.im

1. 新手常犯的錯誤

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

public static void main(String[] args) {List<String> platformList = new ArrayList<>();platformList.add("博客園");platformList.add("CSDN");platformList.add("掘金");for (String platform : platformList) {if (platform.equals("博客園")) {platformList.remove(platform);}}System.out.println(platformList); }

然后滿懷信心的去運行,結果竟然拋java.util.ConcurrentModificationException異常了,翻譯成中文就是:并發修改異常。

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

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


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

然后再來看下ArrayList類的Iterator是如何實現的呢?

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

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

platformList.remove(platform);

modCount的值就被修改成了4。

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

既然不能使用foreach來實現,那么我們該如何實現呢?

主要有以下3種方法:

  • 使用Iterator的remove()方法
  • 使用for循環正序遍歷
  • 使用for循環倒序遍歷
  • 接下來一一講解。

    2. 使用Iterator的remove()方法

    使用Iterator的remove()方法的實現方式如下所示:

    public static void main(String[] args) {List<String> platformList = new ArrayList<>();platformList.add("博客園");platformList.add("CSDN");platformList.add("掘金");Iterator<String> iterator = platformList.iterator();while (iterator.hasNext()) {String platform = iterator.next();if (platform.equals("博客園")) {iterator.remove();}}System.out.println(platformList); }

    輸出結果為:

    [CSDN, 掘金]

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

    讓我們看下它的源碼:


    可以看出,每次刪除一個元素,都會將modCount的值重新賦值給expectedModCount,這樣2個變量就相等了,不會觸發java.util.ConcurrentModificationException異常。

    3. 使用for循環正序遍歷

    使用for循環正序遍歷的實現方式如下所示:

    public static void main(String[] args) {List<String> 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); }

    這種實現方式比較好理解,就是通過數組的下標來刪除,不過有個注意事項就是刪除元素后,要修正下下標的值:

    i = i - 1;

    為什么要修正下標的值呢?

    因為剛開始元素的下標是這樣的:

    第1次循環將元素"博客園"刪除后,元素的下標變成了下面這樣:

    第2次循環時i的值為1,也就是取到了元素”掘金“,這樣就導致元素"CSDN"被跳過檢查了,所以刪除完元素后,我們要修正下下標,這也是上面代碼中i = i - 1;的用途。

    4. 使用for循環倒序遍歷

    使用for循環倒序遍歷的實現方式如下所示:

    public static void main(String[] args) {List<String> 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); }

    這種實現方式和使用for循環正序遍歷類似,不過不用再修正下標,因為剛開始元素的下標是這樣的:

    第1次循環將元素"掘金"刪除后,元素的下標變成了下面這樣:


    image.png

    第2次循環時i的值為1,也就是取到了元素”CSDN“,不會導致跳過元素,所以不需要修正下標。

    作者:申城異鄉人
    原文鏈接:https://juejin.im/post/5e74413cf265da574c569935 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的java list 删除元素_Java面试题:List如何一边遍历,一边删除?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。