<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    春風博客

    春天里,百花香...

    導航

    <2007年12月>
    2526272829301
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345

    統(tǒng)計

    公告

    MAIL: junglesong@gmail.com
    MSN: junglesong_5@hotmail.com

    Locations of visitors to this page

    常用鏈接

    留言簿(11)

    隨筆分類(224)

    隨筆檔案(126)

    個人軟件下載

    我的其它博客

    我的鄰居們

    最新隨筆

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    遍歷并批量刪除容器中元素出現ConcurrentModificationException原因及處置

    在以下四種遍歷過程中,前兩種會拋出ConcurrentModificationException,而后兩種方法是正確的.

    Department類:
    package com.sitinspring;

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    public class Department {
        
    private String name;

        
    private List<Member> memberSheet;

        
    public Department(String name) {
            
    this.name = name;
        }

        
    public void addMemer(Member member) {
            
    if (memberSheet == null) {
                memberSheet 
    = new ArrayList<Member>();
            }

            memberSheet.add(member);
        }

        
    public void printMemberSheet() {
            System.out.println(
    "----部門" + name + "人員名單---");

            
    for (Member member : memberSheet) {
                System.out.println(member);
            }
        }

        
    /**
         * 里面的四個清除過程請分別獨立執(zhí)行
         *
         
    */
        
    public void removeYoungerFromMemberSheet() {    
            
    // 遍歷一:這個處理會拋出java.util.ConcurrentModificationException
            for (Member member : memberSheet) {
                
    if (member.getAge() < 30) {
                    memberSheet.remove(member);
                }
            }
            
            
    // 遍歷二:這個處理也會拋出java.util.ConcurrentModificationException
            for (Iterator it = memberSheet.iterator(); it.hasNext();) {
                Member member 
    = (Member) it.next();

                
    if (member.getAge() < 30) {
                    memberSheet.remove(member);
                }
            }
            
            
    // 遍歷三:這個處理調用Iterator 本身的方法 remove(),會正常執(zhí)行
            for (Iterator it = memberSheet.iterator(); it.hasNext();) {
                Member member 
    = (Member) it.next();

                
    if (member.getAge() < 30) {
                    it.remove();
                }
            }
            
            
    // 遍歷四:這個處理不依賴Iterator,也會正常執(zhí)行
            for (int i=0;i<memberSheet.size();i++) {
                Member member 
    = memberSheet.get(i);

                
    if (member.getAge() < 30) {
                    memberSheet.remove(member);
                }
            }
        }

        
    public String toString() {
            
    return name;
        }

        
    public String getName() {
            
    return name;
        }

        
    public static void main(String[] args) {
            Department resarchDept 
    = new Department("研發(fā)部門");
            resarchDept.addMemer(
    new Member("張三"38));
            resarchDept.addMemer(
    new Member("李四"24));
            resarchDept.addMemer(
    new Member("王五"30));
            resarchDept.addMemer(
    new Member("錢七"22));
            resarchDept.addMemer(
    new Member("孫八"39));
            resarchDept.addMemer(
    new Member("周九"30));

            resarchDept.removeYoungerFromMemberSheet();
            resarchDept.printMemberSheet();
        }
    }

    Member類:
    package com.sitinspring;

    public class Member{
        
    private String name;
        
    private int age;
        
    private Department department;
        
        
    public Member(String name,int age){
            
    this.name=name;
            
    this.age=age;
        }
        
        
    public String toString(){
            StringBuffer sb
    =new StringBuffer();
            sb.append(
    "員工名="+name);
            sb.append(
    " 年齡="+age);
            
            
    if(department!=null){
                sb.append(
    " 所屬部門="+department);
            }
            
            
    return sb.toString();
        }
        
        
    public void changeNewDepartment(Department newDepartment) {
            department.removeMemer(name);
            newDepartment.addMemer(
    this);
        }
        
        
    public String getName() {
            
    return name;
        }

        
    public void setDepartment(Department department) {
            
    this.department = department;
        }
    }

    為什么會發(fā)生這樣的結果呢?這是因為

    "當使用 fail-fast iterator 對 Collection 或 Map 進行迭代操作過程中嘗試直接修改 Collection / Map 的內容時,即使是在單線程下運行, java.util.ConcurrentModificationException 異常也將被拋出。
    Iterator 是工作在一個獨立的線程中,并且擁有一個 mutex 鎖。 Iterator 被創(chuàng)建之后會建立一個指向原來對象的單鏈索引表,當原來的對象數量發(fā)生變化時,這個索引表的內容不會同步改變,所以當索引指針往后移動的時候就找不到要迭代的對象,所以按照 fail-fast 原則 Iterator 會馬上拋出 java.util.ConcurrentModificationException 異常。
    所以 Iterator 在工作的時候是不允許被迭代的對象被改變的。但你可以使用 Iterator 本身的方法 remove() 來刪除對象, Iterator.remove() 方法會在刪除當前迭代對象的同時維護索引的一致性。
    "

    上述這段資料來自http://hi.baidu.com/xjenator/blog/item/23b235a89041d4b0ca130c16.html.

    java.util包中很多迭代器都是所謂的fail-fast迭代器.這些迭代器如果發(fā)現集合被修改,而且不是通過迭代器本身,那么拋出一個異常進行清除-ConcurrentModificationException-從而避免不安全行為的發(fā)生.

    因此,第三種采用it.remove();不會出現任何異常,而第四不依賴于Iterator而依賴于索引當然更不會出現異常.

    代碼下載:
    http://m.tkk7.com/Files/sitinspring/ConcurrentModificationTest20071203210937.rar

    posted on 2007-12-03 21:04 sitinspring 閱讀(1884) 評論(2)  編輯  收藏 所屬分類: Java基礎

    評論

    # re: 遍歷并批量刪除容器中元素出現ConcurrentModificationException原因及處置 2007-12-04 09:09 BeanSoft

    不錯!  回復  更多評論   

    # re: 遍歷并批量刪除容器中元素出現ConcurrentModificationException原因及處置 2008-03-01 08:51 leequn1984

    第四種遍歷方法雖然不會拋 ConcurrentModificationException異常,但運行結果不是所期望的.應該寫成
    for (int i = membeerSheet.size() - 1;i >= 0; i--) {
    Member member = memberSheet.get(i);

    if (member.getAge() < 30) {
    memberSheet.remove(member);
    }
    }
    我的郵件是leequn1984@126.com,歡迎交流.  回復  更多評論   

    sitinspring(http://m.tkk7.com)原創(chuàng),轉載請注明出處.
    主站蜘蛛池模板: 中文字幕免费播放| 色老头综合免费视频| 久久精品人成免费| 亚洲国产精品无码成人片久久| 暖暖免费中文在线日本| 国产大片51精品免费观看| 久久亚洲精品无码网站| 日韩高清在线免费看| 国产亚洲福利精品一区二区| 国产三级电影免费观看| 国产成人+综合亚洲+天堂| 免费播放特黄特色毛片| eeuss免费天堂影院| 亚洲成AV人片在WWW色猫咪| 少妇人妻偷人精品免费视频| 麻豆亚洲av熟女国产一区二| 中文字幕免费在线看线人 | 性一交一乱一视频免费看| 亚洲日韩AV一区二区三区中文| 成全高清视频免费观看| 美女羞羞喷液视频免费| 亚洲中文字幕久久精品无码喷水| 中文字幕不卡免费高清视频| 亚洲视频手机在线| 手机在线毛片免费播放| 特黄特色的大片观看免费视频| 国产亚洲大尺度无码无码专线| 特级无码毛片免费视频尤物| 亚洲av乱码一区二区三区香蕉| 国产又粗又长又硬免费视频| 精品无码一级毛片免费视频观看| 精品亚洲A∨无码一区二区三区| 久久综合AV免费观看| 日韩毛片在线免费观看| 亚洲AV成人一区二区三区AV| 美女视频黄的全免费视频网站| 18禁亚洲深夜福利人口| 亚洲av之男人的天堂网站| 德国女人一级毛片免费| 精品在线免费观看| 亚洲A∨精品一区二区三区下载|