最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中List移除元素的四種方式

 更新時(shí)間:2024年08月27日 11:03:53   作者:遨游在知識(shí)的海洋里無(wú)法自拔  
本文主要介紹了java中List移除元素的四種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

四種方式:

  • 方式一,使用 Iterator ,順序向下,如果找到元素,則使用 remove 方法進(jìn)行移除。
  • 方式二,倒序遍歷 List ,如果找到元素,則使用 remove 方法進(jìn)行移除。
  • 方式三,正序遍歷 List ,如果找到元素,則使用 remove 方法進(jìn)行移除,然后進(jìn)行索引 “自減”。
  • 方式四,使用jdk1.8新增的Stream流操作

1.Iterator 迭代器

	@Test
    public void fun9(){
        List<String> list = new ArrayList<>();
        list.add("趙云");
        list.add("黃忠");
        list.add("馬超");
        list.add("關(guān)羽");
        list.add("張飛");
        // 獲取迭代器
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            String str = it.next();
            if("關(guān)羽".equals(str)){
                it.remove();
            }
        }
        System.out.println(list);
    }

2.倒序遍歷

	@Test
    public void fun10(){
        List<String> list = new ArrayList<>();
        list.add("趙云");
        list.add("黃忠");
        list.add("馬超");
        list.add("關(guān)羽");
        list.add("張飛");
        for (int i = list.size() - 1; i > 0; i--) {
            if("關(guān)羽".equals(list.get(i))){
                list.remove(i);
            }
        }
        System.out.println(list);
    }

3.正序遍歷

 	@Test
    public void fun11(){
        List<String> list = new ArrayList<>();
        list.add("趙云");
        list.add("黃忠");
        list.add("馬超");
        list.add("關(guān)羽");
        list.add("張飛");
        for (int i = 0; i < list.size(); i++) {
            if("關(guān)羽".equals(list.get(i))){
                list.remove(i);
                i--;
            }
        }
        System.out.println(list);
    }

4.Stream流操作(JDK 1.8 +)

	@Test
    public void fun8(){
        List<String> list = new ArrayList<>();
        list.add("趙云");
        list.add("黃忠");
        list.add("馬超");
        list.add("關(guān)羽");
        list.add("張飛");
        // 篩選出不是“關(guān)羽” 的集合
        list = list.stream().filter(e -> !"關(guān)羽".equals(e)).collect(Collectors.toList());
        System.out.println("method4|list=" + list);

    }

問題:

1.為什么不能使用forEach

	@Test
    public void fun5(){
        List<String> list = new ArrayList<>();
        list.add("趙云");
        list.add("黃忠");
        list.add("馬超");
        list.add("關(guān)羽");
        list.add("張飛");
        for (String str :list) {
            if ("張飛".equals(str)){
                list.remove(str);
            }
        }
        System.out.println(list);
    }

在這里插入圖片描述

原因:

foreach方式遍歷元素的時(shí)候,是生成iterator,然后使用iterator遍歷。在生成iterator的時(shí)候,會(huì)保存一個(gè)expectedModCount參數(shù),這個(gè)是生成iterator的時(shí)候List中修改元素的次數(shù)。如果你在遍歷過程中刪除元素,List中modCount就會(huì)變化,如果這個(gè)modCount和exceptedModCount不一致,就會(huì)拋出異常。這個(gè)是為了安全的考慮。如果使用iterator遍歷過程中,使用List修改了元素,可能會(huì)出現(xiàn)不正常的現(xiàn)象。如果使用iterator的remove方法則會(huì)正常,因?yàn)閕terator的remove方法會(huì)在內(nèi)部調(diào)用List的remove方法,但是會(huì)修改excepedModCount的值,因此會(huì)正常運(yùn)行。

2.為什么forEach 刪除倒數(shù)第二元素不會(huì)出現(xiàn)異常

 	@Test
    public void fun12() {
        List<String> list = new ArrayList<>();
        list.add("趙云");
        list.add("黃忠");
        list.add("馬超");
        list.add("關(guān)羽");
        list.add("張飛");
        for (String str:list) {
            if("關(guān)羽".equals(str)){
                list.remove(str);
            }
            System.out.println(str);
        }
    }

在這里插入圖片描述

仔細(xì)觀察發(fā)現(xiàn)集合最后一個(gè)元素(“張飛”)并沒有被遍歷出來,因?yàn)楫?dāng)我們移除倒數(shù)第二個(gè)元素(“關(guān)羽”)時(shí) cursor(游標(biāo))為 4 ,list 中size 屬性的值會(huì)發(fā)生變化(5 - 1 = 4)變?yōu)?4,所以下面代碼返回 false ,也就不會(huì)繼續(xù)向下遍歷。這也是能夠正常執(zhí)行的原因,因?yàn)槿绻^續(xù)遍歷就會(huì)出現(xiàn)問題1 中的情況,在進(jìn)行checkForComodification() 時(shí),因?yàn)?modCount 發(fā)生了變化,而expectedModCount 并沒有發(fā)生變化,所以會(huì)出現(xiàn) ConcurrentModificationException異常。

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();
            }
        }
 public boolean hasNext() {
            return cursor != size;
        }
public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

3 普通正序 for 循環(huán)為什么要 i –

因?yàn)楸闅v過程中進(jìn)行remove 操作時(shí),該位置后面的元素會(huì)擠到前面來,這時(shí)候會(huì)發(fā)生一種情況就是原來元素的位置會(huì)被他后面的元素取代,而該位置已經(jīng)遍歷過了,所以該元素不會(huì)背遍歷。 所以要進(jìn)行 i-- 操作從該位置重新遍歷。

	@Test
    public void fun11(){
        List<String> list = new ArrayList<>();
        list.add("趙云");
        list.add("黃忠");
        list.add("馬超");
        list.add("關(guān)羽");
        list.add("張飛");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
            if("關(guān)羽".equals(list.get(i))){
                list.remove(i);
            }
        }
        System.out.println(list);
    }

就是下面的情況 “張飛” 不見了…

在這里插入圖片描述

4 為什么倒序for 循環(huán)可以

當(dāng)我們倒序遍歷元素的時(shí)候,無(wú)論刪除元素之后的元素怎么移動(dòng),之前的元素對(duì)應(yīng)的索引(index)是不會(huì)發(fā)生變化的,所以在刪除元素的時(shí)候不會(huì)發(fā)生問題。

到此這篇關(guān)于java中List移除元素的四種方式的文章就介紹到這了,更多相關(guān)java List移除元素內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Cache擴(kuò)展功能實(shí)現(xiàn)過程解析

    Spring Cache擴(kuò)展功能實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Spring Cache擴(kuò)展功能實(shí)現(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 詳解java中繼承關(guān)系類加載順序問題

    詳解java中繼承關(guān)系類加載順序問題

    這篇文章主要介紹了詳解java中繼承關(guān)系類加載順序問題的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 四步輕松搞定java web每天定時(shí)執(zhí)行任務(wù)

    四步輕松搞定java web每天定時(shí)執(zhí)行任務(wù)

    本篇文章主要介紹了四步輕松搞定java web每天定時(shí)執(zhí)行任務(wù),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • 利用Sharding-Jdbc組件實(shí)現(xiàn)分表

    利用Sharding-Jdbc組件實(shí)現(xiàn)分表

    這篇文章主要為大家詳細(xì)介紹了利用Sharding-Jdbc組件實(shí)現(xiàn)分表,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Java catch與throw同時(shí)使用的操作

    Java catch與throw同時(shí)使用的操作

    這篇文章主要介紹了Java catch與throw同時(shí)使用的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 深入解析Spring Boot熱部署與性能優(yōu)化實(shí)踐指南

    深入解析Spring Boot熱部署與性能優(yōu)化實(shí)踐指南

    本文從Spring Boot熱部署原理入手,結(jié)合生產(chǎn)環(huán)境中的實(shí)戰(zhàn)經(jīng)驗(yàn),深入分析熱部署的底層實(shí)現(xiàn)機(jī)制,并給出性能優(yōu)化的實(shí)踐建議,幫助開發(fā)者在提升開發(fā)效率的同時(shí)保障系統(tǒng)性能,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2025-10-10
  • Java中MyBatis的結(jié)果映射詳解

    Java中MyBatis的結(jié)果映射詳解

    這篇文章主要介紹了Java中MyBatis的結(jié)果映射詳解,MyBatis 支持對(duì)各種單表查詢、關(guān)聯(lián)查詢等各種復(fù)雜查詢的結(jié)果進(jìn)行映射,MyBatis 是一款優(yōu)秀的持久層框架,它的強(qiáng)大之處正是 SQL 語(yǔ)句映射,這一章介紹常用的結(jié)果映射,需要的朋友可以參考下
    2023-08-08
  • Eclipse手動(dòng)導(dǎo)入DTD文件實(shí)現(xiàn)方法解析

    Eclipse手動(dòng)導(dǎo)入DTD文件實(shí)現(xiàn)方法解析

    這篇文章主要介紹了Eclipse手動(dòng)導(dǎo)入DTD文件實(shí)現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Spring?Boot項(xiàng)目集成Knife4j接口文檔的實(shí)例代碼

    Spring?Boot項(xiàng)目集成Knife4j接口文檔的實(shí)例代碼

    Knife4j就相當(dāng)于是swagger的升級(jí)版,對(duì)于我來說,它比swagger要好用得多<BR>,這篇文章主要介紹了Spring?Boot項(xiàng)目集成Knife4j接口文檔的示例代碼,需要的朋友可以參考下
    2021-12-12
  • 詳解mybatis 批量更新數(shù)據(jù)兩種方法效率對(duì)比

    詳解mybatis 批量更新數(shù)據(jù)兩種方法效率對(duì)比

    這篇文章主要介紹了詳解mybatis 批量更新數(shù)據(jù)兩種方法效率對(duì)比,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02

最新評(píng)論

崇州市| 龙泉市| 云浮市| 定结县| 讷河市| 祁东县| 莱阳市| 兴业县| 鄱阳县| 鹿泉市| 博爱县| 洛隆县| 嘉义县| 三亚市| 西吉县| 龙南县| 内黄县| 榕江县| 娱乐| 福清市| 大悟县| 布尔津县| 大关县| 香格里拉县| 宜丰县| 若尔盖县| 谢通门县| 会理县| 南平市| 嘉定区| 庆阳市| 黄骅市| 博客| 平远县| 略阳县| 阳山县| 伊金霍洛旗| 安达市| 昌宁县| 蒙城县| 思南县|