国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java list安全刪除元素詳解

這篇具有很好參考價值的文章主要介紹了Java list安全刪除元素詳解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

背景

前一段時間被問到了關(guān)于 List 集合的安全刪除元素問題。一時間沒反應(yīng)過來這問題問的是什么,安全體現(xiàn)在什么地方,線程安全?線程安全可以保證元素粒度的數(shù)據(jù)唯一嗎?刪除是指什么,list.remove()?
帶著這些疑問,重溫了一下Java的集合知識。

問題分析

List為什么需要安全移除?

我不理解什么是安全刪除,我開發(fā)的業(yè)務(wù)中也很少說需要用到remove的,我只記得一般用的話,都是remove(index)這樣。寫個測試代碼看看

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");

for (int i = 0; i < list.size(); i++) {
    if ("B".equals(list.get(i))) {
        list.remove(i);
        continue;
    }
    System.out.println(list.get(i));
}

這段代碼的目的就是想把B移除,最后期望的輸出只有AC兩個字母,看一下運(yùn)行結(jié)果:
Java list安全刪除元素詳解
目的達(dá)到了,那這個刪除不就是安全刪除嗎?怎么才算安全刪除?

于是我又加了一堆 A B C D E F G,還是刪除B,最后打印的數(shù)組也是正確的。

直到我突發(fā)奇想,多加了一個連續(xù)重復(fù)的字母B,問題出現(xiàn)了

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("B");
list.add("C");
list.add("D");

for (int i = 0; i < list.size(); i++) {
    if ("B".equals(list.get(i))) {
        list.remove(i);
        continue;
    }
//            System.out.println(list.get(i));
}
System.out.println(list);

我打印的結(jié)果是

[A, B, C, D]

為什么會這樣呢?其實(shí)原理很簡單,就是因?yàn)長ist.remove刪除元素后,數(shù)組的整體下標(biāo)會往前移動,原本的位置被遍歷過了,就會被跳過。

A B B C D 遍歷index
0 1 2 3 4 0遍歷元素A,不作任何操作
0 1 2 3 4 1遍歷第一個B,移除B
0 1 2 3 2遍歷C,已經(jīng)跳過第二個B
0 1 2 3 3遍歷D,后面沒有元素了,結(jié)束

那簡單啊,我記得list移除操作可以remove(object),試一下

for (String element : list) {
    if (element.equals("B")) {
        // 在for循環(huán)中直接使用list.remove()方法刪除元素
        list.remove(element);
    }
}
System.out.println(list);

直接給我報錯了
Java list安全刪除元素詳解
分析了一下ArrayList的源碼,原來增強(qiáng)for循環(huán)的實(shí)現(xiàn)原理是使用了Iterator迭代器,而ArrayList重寫了迭代器的next方法,每次迭代時會檢查是否做了新增或者刪除操作(modCount++),而這些操作都會導(dǎo)致期待值與實(shí)際值不對等,從而拋出異常。
說簡單點(diǎn)就是和兩個B字母無關(guān),是你使用了增強(qiáng)for循環(huán)就不可以在遍歷的時候add和remove。

和上面相同的代碼原理是這樣的,使用迭代器遍歷list,隨后用ArrayList的remove

        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            if (element.equals("B")) {
                list.remove(element); // 直接使用list.remove()方法刪除元素
            }
        }

試了一下,也是報錯,一模一樣的問題。

到現(xiàn)在為止,我們理解了怎樣場景下移除元素是不安全的。不安全包括:

  1. 下標(biāo)上移導(dǎo)致的檢查丟失
  2. ConcurrentModificationException的發(fā)生

問題解決

方案一:

查閱了Java的API文檔之后,上面提到,使用Iterator自己的remove方法可以安全地移除元素。

        List<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("B");
        list.add("C");
        list.add("D");
        
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            if (element.equals("B")) {
                iterator.remove(); // 安全移除元素
            }
        }

        System.out.println(list);
        

輸出的結(jié)果為

[A, C, D]

方案二

Java8之后list新增了一個api removeIf,這個也可以做安全刪除

list.removeIf(s -> s.equals("B"));

輸出的結(jié)果為

[A, C, D]

方案三

使用removeAll方法

        List<String> elementsToRemove = new ArrayList<>();
        for (String element : list) {
            if (element.equals("B")) {
                elementsToRemove.add(element);
            }
        }

        list.removeAll(elementsToRemove);

這樣執(zhí)行的結(jié)果也是正確的文章來源地址http://www.zghlxwxcb.cn/news/detail-492685.html

到了這里,關(guān)于Java list安全刪除元素詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Java從List中刪除元素的正確用法

    Java從List中刪除元素的正確用法

    還是先舉個例子,你侄女對天文知識感興趣,然后你就用程序?qū)懥颂栂稻糯笮窍担ㄋ?、金星、地球、火星、木星、土星、天王星、海王星、冥王星)的運(yùn)行軌跡圖,然后拿給侄女看。然后她說錯了錯了,你的知識太舊了,多了一顆星。根據(jù)2006年8月24日國際天文聯(lián)合大會召

    2024年02月09日
    瀏覽(26)
  • Java 定義返回一個不能被修改、刪除元素的List

    Java 定義返回一個不能被修改、刪除元素的List

    ? 為啥突然分享下這個,也是從mybatis源碼看到了,所以想分享下: org.apache.ibatis.plugin.InterceptorChain ? 使用?Collections.unmodifiableList(); 示例: 運(yùn)行效果: 不給動。 ?

    2024年02月13日
    瀏覽(45)
  • python 一次性刪除列表(list)的空白元素(空內(nèi)容) 或者 一次性刪除列表(list)中的指定元素

    看看下述代碼: 輸出: 當(dāng)你遇見這種情況,有哪些方法來去除里面的空內(nèi)容呢(即 \\\'\\\' )? 1.1 刪除空內(nèi)容(方法一) : 輸出: 1.2 刪除空內(nèi)容(方法二) : 需要 配合 lambda 表達(dá)式 一起使用! 輸出: 2.3 刪除指定內(nèi)容 : 輸出: 注 :此方法既可以刪除空元素,也可以刪除指

    2024年02月03日
    瀏覽(304)
  • List集合刪除指定元素-四種方法

    List集合刪除指定元素-四種方法

    第一種 for循環(huán) 輸出結(jié)果為 第二種 迭代器 輸出結(jié)果為 第三種 stream流 這種過濾是留下符合條件的元素 輸出結(jié)果為 第四種 removeIf 方法以及 方法引用 removeIf 方法是jdk1.8 Collection以及其子類新增的,作用是過濾指定條件的元素 輸出結(jié)果為 總結(jié) 不言而喻,第四種方法最好用。

    2024年02月09日
    瀏覽(26)
  • 8 種循環(huán)刪除 List 元素的方法:

    public?ListString?list?=?Arrays.asList(\\\"張三\\\",?\\\"李四\\\",?\\\"王五\\\",?\\\"老六\\\",?\\\"李東\\\",?\\\"李想\\\",?\\\"茍八\\\"); 普通 for 循環(huán)刪除(不可靠) 普通 for 循環(huán)提取變量刪除(拋異常) 普通 for 循環(huán)倒序刪除(可靠) public?void?remove()?{ ????ListString?list?=?new?ArrayList(initList); ????for?(int?i?=?li

    2024年01月20日
    瀏覽(24)
  • list刪除重復(fù)元素幾種思路

    list刪除重復(fù)元素幾種思路

    distinct()是Java 8 中 Stream 提供的方法,返回的是由該流中不同元素組成的流。distinct()使用 hashCode() 和 eqauls() 方法來獲取不同的元素。 因此,需要去重的類必須實(shí)現(xiàn) hashCode() 和 equals() 方法。換句話講,我們可以通過重寫定制的 hashCode() 和 equals() 方法來達(dá)到某些特殊需求的去重

    2024年02月14日
    瀏覽(21)
  • Python list列表刪除元素(4種方法)

    Python list列表刪除元素(4種方法)

    在?Python列表中刪除元素主要分為以下 3 種場景: 根據(jù)目標(biāo)元素所在位置的索引進(jìn)行刪除,可以使用 del 或者 pop() 方法; 根據(jù)元素本身的值進(jìn)行刪除,可使用列表(list類型)提供的 remove() 方法; 將列表中所有元素全部刪除,可使用列表(list類型)提供的 clear() 方法

    2024年02月02日
    瀏覽(117)
  • STL--list如何實(shí)現(xiàn)元素的插入和刪除

    STL--list如何實(shí)現(xiàn)元素的插入和刪除

    在C++標(biāo)準(zhǔn)模板庫(STL)中,std::list 是一個雙向鏈表。由于它的雙向鏈表特性,std::list 支持在任何位置高效地插入和刪除元素。 元素插入: ●使用 push_back() 在列表尾部添加元素; ●使用 push_front() 在列表頭部添加元素; ●使用 insert() 在指定位置插入元素。這需要一個迭代器

    2024年04月12日
    瀏覽(28)
  • <List<Map<String,String>>> 刪除元素常見的誤區(qū)以及刪除方法

    看到這么標(biāo)題可能覺得這個真是太easy了,不就remove嗎,分分鐘搞定。 但結(jié)果卻出乎意料,下面我們來j簡單說說list刪除數(shù)據(jù)可能遇到的坑: 先說明我們可能會遇到的兩個問題: 1.java.lang.IndexOutOfBoundsException(索引越界) 2.java.util.ConcurrentModificationException(并發(fā)修改異常) 開始測試

    2024年02月12日
    瀏覽(26)
  • <List<Map<String,String>>> 刪除元素常見的誤區(qū)

    看到這么標(biāo)題可能覺得這個真是太easy了,不就remove嗎,分分鐘搞定。 但結(jié)果卻出乎意料,下面我們來j簡單說說list刪除數(shù)據(jù)可能遇到的坑: 先說明我們可能會遇到的兩個問題: 1.java.lang.IndexOutOfBoundsException(索引越界) 2.java.util.ConcurrentModificationException(并發(fā)修改異常) 開始測試

    2024年02月12日
    瀏覽(29)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包