欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java 如何在list中刪除我指定的對象

 更新時間:2021年11月17日 09:03:45   作者:DobyJin  
這篇文章主要介紹了java 如何在list中刪除我指定的對象,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

遍歷list,刪除指定對象的三種方式

1、再定義一個List,用來保存需要刪除的對象

修改部分代碼:

 List<User> userRemove = new ArrayList<User>();
        //找出要刪除的用戶
        System.err.println("要刪除的用戶:");
        for (User result : list)
        {
            if (result.getId() == 1 || result.getId() == 3)
            {
                userRemove.add(result);
                System.err.println("id:" + result.getId() + "\tname:" + result.getName());
            }
        }
        list.removeAll(userRemove);
        //剩下的用戶
        System.err.println("剩下的用戶:");
        for (User result : list)
        {
            System.err.println("id:" + result.getId() + "\tname:" + result.getName());
        }

2、不用for-each循環(huán),使用倒序循環(huán)刪除

for(int i=list.size()-1;i>=0;i--)
                {
                    User result = list.get(i);
                    if (result.getId() == 3)
                    {
                        list.remove(result);
                        System.err.println("id: " + result.getId() + "\tname: " + result.getName());
                    }
                }

3、用迭代器刪除

Iterator<User> it = list.iterator();
        while (it.hasNext())
        {
            User userObj = it.next();
            if (userObj.getId() == 3)
            {
                it.remove();
            }
        }
        //剩下的用戶
        System.err.println("剩下的用戶:");
        for (User result : list)
        {
            System.err.println("id:" + result.getId() + "\tname:" + result.getName());
        }

PS: 用for-each遍歷 實際上使用的是Iterator迭代器

Iterator的工作機制

Iterator是工作在一個獨立的線程中,并且擁有一個 mutex鎖,就是說Iterator在工作的時候,是不允許被迭代的對象被改變的。

Iterator被創(chuàng)建的時候,建立了一個內(nèi)存索引表(單鏈表),這 個索引表指向原來的對象,當原來的對象數(shù)量改變的時候,這個索引表的內(nèi)容沒有同步改變,所以當索引指針往下移動的時候,便找不到要迭代的對象,于是產(chǎn)生錯 誤。

List、Set等是動態(tài)的,可變對象數(shù)量的數(shù)據(jù)結(jié)構(gòu),但是Iterator則是單向不可變,只能順序讀取,不能逆序操作的數(shù)據(jù)結(jié)構(gòu),當 Iterator指向的原始數(shù)據(jù)發(fā)生變化時,Iterator自己就迷失了方向。

三種方式 方便以后學習 !

List集合刪除元素的正確姿勢

在閱讀阿里巴巴規(guī)約的時候發(fā)現(xiàn)有一條規(guī)約是關(guān)于List的【不要在foreach里面進行元素的remove/add操作,remove請使用Iterator方式】。然后想起以前自己做項目的時候刪除某一元素的邏輯報下標越界錯誤,那時候記得處理是用一新的List進行存儲,然后整體從原List移除所有符合規(guī)則的元素,現(xiàn)在做一總結(jié)。用這個Iterator主要可以避免下標越界或者遍歷是漏掉符合規(guī)則的下一個數(shù)據(jù)。

先拉出來正確刪除元素的姿勢。正確姿勢是利用Iterator的remove方法。具體操作如下:

public static void main(String[] args) {
        List<Integer> lists = new ArrayList<Integer>();
        lists.add(1);
        lists.add(2);
        lists.add(3);
        lists.add(4);
        lists.add(5);
        Iterator<Integer> iterator = lists.iterator();
        while (iterator.hasNext()){
            Integer obj = iterator.next();
            if(3==obj || 4==obj){
                iterator.remove();
            }
        }
        System.out.println(lists);
    }

附上自己比較笨的操作方式:

public static void main(String[] args){
            List<Integer> lists = new ArrayList<Integer>();
            List<Integer> listscopy = new ArrayList<>();
            lists.add(1);
            lists.add(2);
            lists.add(3);
            lists.add(4);
            lists.add(5);
            int size = lists.size();
            for (int i = 0; i < lists.size(); i++) {
                if(3==lists.get(i) || 4 == lists.get(i)){
                    listscopy.add(lists.get(i));
                }
            }
            lists.removeAll(listscopy);
            System.out.println(lists);
        }

常用的錯誤方式有以下三種

第一種方式,多出現(xiàn)下標越界問題。這個主要原因是因為我們在循環(huán)遍歷時,將我們的長度進行定值確定。而忽略掉在滿足條件時,list的長度是減少的。

public static void main(String[] args) {
 List<Integer> lists = new ArrayList<Integer>();
        lists.add(1);
        lists.add(2);
        lists.add(3);
        lists.add(4);
        lists.add(5);
        int size = lists.size();  // 定長設置,會造成元素下標越界,如果將for中變量直接換成lists.size()可以嗎?
        for (int i = 0; i < size; i++) {
            if(3==lists.get(i) || 4 == lists.get(i)){
                lists.remove(i); //lists.remove(lists.get(i));
            }
        }
        System.out.println(lists);
 }

第二種方式也就是上面的注釋所說,既然會出現(xiàn)下標越界,那我就利用動態(tài)的大小不就可以了,但是利用這種方法會產(chǎn)生另外一種情況,就是會忽略掉remove元素后面的一個元素,這個是因為刪除符合規(guī)則的元素后,list長度減一,而同時后面的元素往前補一位,造成當前i值下對應兩個元素。

public static void main(String[] args) {
        List<Integer> lists = new ArrayList<Integer>();
        lists.add(1);
        lists.add(2);
        lists.add(3);
        lists.add(4);
        lists.add(5);
        int size = lists.size();
        for (int i = 0; i < lists.size(); i++) {
            if(3==lists.get(i) || 4 == lists.get(i)){
                lists.remove(i); //lists.remove(lists.get(i));
            }
        }
        System.out.println(lists); // 打印[1, 2, 4, 5] 此時會將4忽略掉
    }

第三種方式是利用增強FOR循環(huán)造成的。這種方式會直接給報錯:

ERRORInfo:
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
    at java.util.ArrayList$Itr.next(ArrayList.java:851)
public static void main(String[] args) {
        List<Integer> lists = new ArrayList<Integer>();
        lists.add(1);
        lists.add(2);
        lists.add(3);
        lists.add(4);
        lists.add(5);
       for (Integer i : lists){
           if(3==i || 4==i){
               lists.remove(i);
           }
       }
        System.out.println(lists);
    }

這種情況下。主要是集合遍歷是使用Iterator, Iterator是工作在一個獨立的線程中,并且擁有一個互斥鎖。Iterator 被創(chuàng)建之后會建立一個指向原來對象的單鏈索引表,當原來的對象數(shù)量發(fā)生變化時,這個索引表的內(nèi)容不會同步改變,所以當索引指針往后移動的時候就找不到要迭代的對象,所以按照 fail-fast原則 Iterator 會馬上拋出java.util.ConcurrentModificationException 異常。所以 Iterator 在工作的時候是不允許被迭代的對象被改變的。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java8特性使用Function代替分支語句

    Java8特性使用Function代替分支語句

    這篇文章主要介紹了Java8特性使用Function代替分支語句,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Java日期時間與正則表達式超詳細整理(適合新手入門)

    Java日期時間與正則表達式超詳細整理(適合新手入門)

    如果使用得當,正則表達式是匹配各種模式的強大工具,下面這篇文章主要給大家介紹了關(guān)于Java日期時間與正則表達式超詳細整理的相關(guān)資料,本文非常適合新手入門,需要的朋友可以參考下
    2023-04-04
  • java實現(xiàn)多人聊天室可視化

    java實現(xiàn)多人聊天室可視化

    這篇文章主要為大家詳細介紹了java實現(xiàn)多人聊天室可視化,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 詳解Spring Boot下Druid連接池的使用配置分析

    詳解Spring Boot下Druid連接池的使用配置分析

    本篇文章主要介紹了詳解Spring Boot下Druid連接池的使用配置分析,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • C++內(nèi)存管理看這一篇就夠了

    C++內(nèi)存管理看這一篇就夠了

    這篇文章主要介紹了C/C++中的內(nèi)存管理小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-08-08
  • mybatis中的延遲加載類型及設定詳解

    mybatis中的延遲加載類型及設定詳解

    這篇文章主要介紹了mybatis中的延遲加載類型及設定詳解,MyBatis中的延遲加載,也稱為懶加載,是指在進行關(guān)聯(lián)查詢時,按照設置延遲規(guī)則推遲對關(guān)聯(lián)對象的select查詢,延遲加載可以有效的減少數(shù)據(jù)庫壓力,需要的朋友可以參考下
    2023-10-10
  • Java Swagger技術(shù)使用指南

    Java Swagger技術(shù)使用指南

    Swagger 是一個規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化 RESTful 風格的 Web 服務??傮w目標是使客戶端和文件系統(tǒng)作為服務器以同樣的速度來更新。文件的方法,參數(shù)和模型緊密集成到服務器端的代碼,允許API來始終保持同步
    2021-09-09
  • maven項目install時忽略執(zhí)行test方法的總結(jié)

    maven項目install時忽略執(zhí)行test方法的總結(jié)

    這篇文章主要介紹了maven項目install時忽略執(zhí)行test方法的總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java?中的靜態(tài)字段和靜態(tài)方法?

    Java?中的靜態(tài)字段和靜態(tài)方法?

    這篇文章主要介紹了Java中的靜態(tài)字段和靜態(tài)方法,文章圍繞Java?靜態(tài)方法展開詳細內(nèi)容,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-03-03
  • Java調(diào)用windows系統(tǒng)的CMD命令并啟動新程序

    Java調(diào)用windows系統(tǒng)的CMD命令并啟動新程序

    本文教你如何使用java程序調(diào)用windows系統(tǒng)的CMD命令啟動新程序方法,需要的朋友可以參考下
    2023-05-05

最新評論