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

歡迎訪問 生活随笔!

生活随笔

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

java

Java集合—List如何一边遍历,一边删除?

發(fā)布時間:2024/4/15 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java集合—List如何一边遍历,一边删除? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文作者:申城異鄉(xiāng)人

原文地址:【Java面試題】List如何一邊遍歷,一邊刪除?

目錄

1. 新手常犯的錯誤

2. 使用Iterator的remove()方法

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

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

5.1 使用removeIf()方法(推薦)

5.2 使用for循環(huán)正序遍歷,是否需要修正下標?


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

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); }

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

?

是不是很懵,心想這是為什么呢?讓我們首先看下上面這段代碼生成的字節(jié)碼,如下所示:

?

由此可以看出,foreach循環(huán)在實際執(zhí)行時,其實使用的是Iterator,使用的核心方法是hasnext()和next()。然后再來看下ArrayList類的Iterator是如何實現(xiàn)的呢?

?

可以看出,調(diào)用next()方法獲取下一個元素時,第一行代碼就是調(diào)用了checkForComodification();,而該方法的核心邏輯就是比較modCount和expectedModCount這2個變量的值。在上面的例子中,剛開始modCount和expectedModCount的值都為3,所以第1次獲取元素"博客園"是沒問題的,但是當執(zhí)行完下面這行代碼時:

platformList.remove(platform);

modCount的值就被修改成了4。

?

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

?

既然不能使用foreach來實現(xiàn),那么我們該如何實現(xiàn)呢?主要有以下3種方法:

  • 使用Iterator的remove()方法
  • 使用for循環(huán)正序遍歷
  • 使用for循環(huán)倒序遍歷
  • 2. 使用Iterator的remove()方法

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

    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); }

    輸出結(jié)果為:

    [CSDN, 掘金]

    為什么使用iterator.remove();就可以呢?讓我們看下它的源碼:

    ?

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

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

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

    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); }

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

    i = i - 1;

    為什么要修正下標的值呢?因為剛開始元素的下標是這樣的:

    ?

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

    ?

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

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

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

    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); }

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

    ?

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

    ?

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

    5.1 使用removeIf()方法(推薦)

    從JDK1.8開始,可以使用removeIf()方法來代替?Iterator的remove()方法實現(xiàn)一邊遍歷一邊刪除,其實,IDEA中也會提示:

    ?

    所以原來的代碼:

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

    就可以簡化為如下所示的1行代碼,非常簡潔:

    platformList.removeIf(platform -> "博客園".equals(platform));

    看下removeIf()方法的源碼,會發(fā)現(xiàn)其實底層也是用的Iterator的remove()方法:

    ?

    5.2 使用for循環(huán)正序遍歷,是否需要修正下標?

    先說結(jié)論:需要。不過之前文中舉得例子不是太好,所以好多讀者看完認為不修正下標也是可以的,其實不是,我們換個例子來理解:

    List<String> platformList = new ArrayList<>(); platformList.add("博客園"); platformList.add("博客園"); platformList.add("CSDN"); platformList.add("掘金");for (int i = 0; i < platformList.size(); i++) {String item = platformList.get(i);if ("博客園".equals(item)) {platformList.remove(i);} }System.out.println(platformList);

    輸出結(jié)果:[博客園, CSDN, 掘金]

    可以發(fā)現(xiàn),如果不修正下標,第2個元素“博客園”在循環(huán)遍歷時被跳過了,也就無法刪除,所以一定要修正下標:

    ?

    總結(jié)

    以上是生活随笔為你收集整理的Java集合—List如何一边遍历,一边删除?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 黑鬼大战白妞高潮喷白浆 | 精品1卡二卡三卡四卡老狼 日韩三级网 | 亚洲2022国产成人精品无码区 | 久青草影院 | 亚欧美一区二区三区 | 丝袜 亚洲 另类 国产 制服 | 在线免费观看av片 | 国产网友自拍视频 | 69精品久久久 | 国产8区 | 乱h伦h女h在线视频 99999视频 | 操女人免费视频 | 风流老熟女一区二区三区 | 国产精品扒开腿做爽爽爽a片唱戏 | 一区二区三区xxx | 微拍福利一区二区 | 亚洲第一女人av | jizz久久| 午夜免费观看 | 伊人网五月天 | 五月婷婷六月天 | 男女黄色又爽大片 | 99精品在线观看视频 | 中文字幕乱码中文乱码b站 国产一区二区三区在线观看视频 | 国产精品入口久久 | 亚洲精品日产精品乱码不卡 | 夜色综合网 | 亚洲最大视频网站 | 久久亚洲精 | 国产网站久久 | 天天操天天草 | 999超碰 | 色亭亭 | 不卡av免费在线观看 | 国产一级爱c视频 | 夜夜操av | 狠狠操导航 | 亚洲国产精品成人午夜在线观看 | 日本黄区免费视频观看 | 毛片视频观看 | 日日插插 | 在线免费观看www | 久久免费黄色网址 | 免费人成在线观看网站 | 精品国产一区在线观看 | 国产日韩亚洲欧美 | 无限国产资源 | 黄色一级片免费 | 国产精品精品久久久 | 性少妇mdms丰满hdfilm | 欧美巨乳在线观看 | 亚洲精品国产一区 | 亚洲第一欧美 | 亚洲网站免费观看 | 久久色图 | 一二三区av | 欧美黄色性生活 | 激情成人综合网 | 一级片观看 | 亚洲成人福利视频 | 电影《走路上学》免费 | 欧美又粗又大xxxxbbbb疯狂 | 日韩欧美国产电影 | av成人免费观看 | 99久久久无码国产精品性 | 永久免费无码av网站在线观看 | 丰满少妇熟乱xxxxx视频 | 高潮毛片无遮挡免费看 | 国产熟女高潮一区二区三区 | 亚洲精品视频一区 | 亚洲第一综合网站 | 国产美女极度色诱视频www | jizz成人| 成人在线高清视频 | 色婷婷一区 | 激情欧美一区二区三区精品 | 日批毛片 | 亚洲天堂一区二区在线 | 看免费一级片 | wwwxxx日本 | 免费国偷自产拍精品视频 | 亚洲爱爱片 | 久久99色| 久久影片 | 色七七网站 | 在线观看日韩 | 国产又色又爽又黄又免费 | 91人人草| 环太平洋3:泰坦崛起 | 老司机免费视频 | 国产一级高清 | 日韩第六页 | www夜片内射视频日韩精品成人 | 91久久久久久久久久久久久 | 国产美女免费网站 | 国产精品一区二区三区免费看 | 69xx国产| 爱啪啪影视 | 国内9l自拍|