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

java 如何在list中刪除我指定的對(duì)象

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

遍歷list,刪除指定對(duì)象的三種方式

1、再定義一個(gè)List,用來(lái)保存需要?jiǎng)h除的對(duì)象

修改部分代碼:

 List<User> userRemove = new ArrayList<User>();
        //找出要?jiǎng)h除的用戶
        System.err.println("要?jiǎng)h除的用戶:");
        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遍歷 實(shí)際上使用的是Iterator迭代器

Iterator的工作機(jī)制

Iterator是工作在一個(gè)獨(dú)立的線程中,并且擁有一個(gè) mutex鎖,就是說(shuō)Iterator在工作的時(shí)候,是不允許被迭代的對(duì)象被改變的。

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

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

三種方式 方便以后學(xué)習(xí) !

List集合刪除元素的正確姿勢(shì)

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

先拉出來(lái)正確刪除元素的姿勢(shì)。正確姿勢(shì)是利用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);
        }

常用的錯(cuò)誤方式有以下三種

第一種方式,多出現(xiàn)下標(biāo)越界問(wèn)題。這個(gè)主要原因是因?yàn)槲覀冊(cè)谘h(huán)遍歷時(shí),將我們的長(zhǎng)度進(jìn)行定值確定。而忽略掉在滿足條件時(shí),list的長(zhǎng)度是減少的。

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();  // 定長(zhǎng)設(shè)置,會(huì)造成元素下標(biāo)越界,如果將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);
 }

第二種方式也就是上面的注釋所說(shuō),既然會(huì)出現(xiàn)下標(biāo)越界,那我就利用動(dòng)態(tài)的大小不就可以了,但是利用這種方法會(huì)產(chǎn)生另外一種情況,就是會(huì)忽略掉remove元素后面的一個(gè)元素,這個(gè)是因?yàn)閯h除符合規(guī)則的元素后,list長(zhǎng)度減一,而同時(shí)后面的元素往前補(bǔ)一位,造成當(dāng)前i值下對(duì)應(yīng)兩個(gè)元素。

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] 此時(shí)會(huì)將4忽略掉
    }

第三種方式是利用增強(qiáng)FOR循環(huán)造成的。這種方式會(huì)直接給報(bào)錯(cuò):

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是工作在一個(gè)獨(dú)立的線程中,并且擁有一個(gè)互斥鎖。Iterator 被創(chuàng)建之后會(huì)建立一個(gè)指向原來(lái)對(duì)象的單鏈索引表,當(dāng)原來(lái)的對(duì)象數(shù)量發(fā)生變化時(shí),這個(gè)索引表的內(nèi)容不會(huì)同步改變,所以當(dāng)索引指針往后移動(dòng)的時(shí)候就找不到要迭代的對(duì)象,所以按照 fail-fast原則 Iterator 會(huì)馬上拋出java.util.ConcurrentModificationException 異常。所以 Iterator 在工作的時(shí)候是不允許被迭代的對(duì)象被改變的。

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

相關(guān)文章

  • 大數(shù)組元素差異removeAll與Map效率對(duì)比

    大數(shù)組元素差異removeAll與Map效率對(duì)比

    這篇文章主要介紹了大數(shù)組元素差異removeAll與Map效率對(duì)比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Java之JNDI注入的實(shí)現(xiàn)

    Java之JNDI注入的實(shí)現(xiàn)

    JNDI是Java EE的重要部分,本文主要介紹了Java之JNDI注入的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之健身器材商城系統(tǒng)的實(shí)現(xiàn)

    Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之健身器材商城系統(tǒng)的實(shí)現(xiàn)

    只學(xué)書(shū)上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+Jdbc+Servlet+Ajax+Fileupload+mysql實(shí)現(xiàn)健身器材商城系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2022-03-03
  • 使用Spring自定義實(shí)現(xiàn)IOC和依賴注入(注解方式)

    使用Spring自定義實(shí)現(xiàn)IOC和依賴注入(注解方式)

    這篇文章主要介紹了使用Spring自定義實(shí)現(xiàn)IOC和依賴注入(注解方式),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot之@Aspect注解解讀

    SpringBoot之@Aspect注解解讀

    這篇文章主要介紹了SpringBoot之@Aspect注解解讀,AOP是面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù),而@Aspect 就是把一個(gè)類定義為切面供容器讀取,需要的朋友可以參考下
    2024-01-01
  • Java+opencv3.2.0實(shí)現(xiàn)人臉檢測(cè)功能

    Java+opencv3.2.0實(shí)現(xiàn)人臉檢測(cè)功能

    這篇文章主要為大家詳細(xì)介紹了Java+opencv3.2.0實(shí)現(xiàn)人臉檢測(cè)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • IDEA創(chuàng)建springboot + mybatis項(xiàng)目全過(guò)程(步驟詳解)

    IDEA創(chuàng)建springboot + mybatis項(xiàng)目全過(guò)程(步驟詳解)

    這篇文章主要介紹了IDEA創(chuàng)建springboot + mybatis項(xiàng)目全過(guò)程及步驟詳解,本文通圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java字段Stream排序常用方式

    Java字段Stream排序常用方式

    這篇文章主要給大家介紹了關(guān)于Java字段Stream排序常用方式的相關(guān)資料,我們?cè)谔幚頂?shù)據(jù)的時(shí)候經(jīng)常會(huì)需要進(jìn)行排序后再返回給前端調(diào)用,比如按照時(shí)間升序排序,前端展示數(shù)據(jù)就是按時(shí)間先后進(jìn)行排序,需要的朋友可以參考下
    2023-09-09
  • SpringMVC靜態(tài)資源配置過(guò)程詳解

    SpringMVC靜態(tài)資源配置過(guò)程詳解

    在javaweb項(xiàng)目中配置了DispatcherServlet的情況下,如果不進(jìn)行額外配置的話,幾乎所有的請(qǐng)求都會(huì)走這個(gè)servlet來(lái)處理,默認(rèn)靜態(tài)資源按路徑是訪問(wèn)不到的會(huì)報(bào)404錯(cuò)誤,下面就來(lái)講一講如何配置才能訪問(wèn)到靜態(tài)資源吧
    2022-08-08
  • mybatis mapper互相引用resultMap啟動(dòng)出錯(cuò)的解決

    mybatis mapper互相引用resultMap啟動(dòng)出錯(cuò)的解決

    這篇文章主要介紹了mybatis mapper互相引用resultMap啟動(dòng)出錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評(píng)論

台南县| 兴安县| 新巴尔虎右旗| 正定县| 呼玛县| 兰溪市| 乐山市| 遂溪县| 招远市| 厦门市| 鹰潭市| 乌拉特后旗| 富锦市| 凤翔县| 石渠县| 大田县| 前郭尔| 瑞昌市| 行唐县| 睢宁县| 徐闻县| 三台县| 德惠市| 郧西县| 霸州市| 洛宁县| 曲沃县| 华安县| 塔河县| 本溪市| 鲜城| 奉贤区| 仲巴县| 东宁县| 庄河市| 永康市| 临猗县| 融水| 柘城县| 淅川县| 灯塔市|