<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

    統計

    公告

    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);
            }
        }

        
    /**
         * 里面的四個清除過程請分別獨立執行
         *
         
    */
        
    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(),會正常執行
            for (Iterator it = memberSheet.iterator(); it.hasNext();) {
                Member member 
    = (Member) it.next();

                
    if (member.getAge() < 30) {
                    it.remove();
                }
            }
            
            
    // 遍歷四:這個處理不依賴Iterator,也會正常執行
            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("研發部門");
            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;
        }
    }

    為什么會發生這樣的結果呢?這是因為

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

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

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

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

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

    posted on 2007-12-03 21:04 sitinspring 閱讀(1885) 評論(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)原創,轉載請注明出處.
    主站蜘蛛池模板: 亚洲AⅤ男人的天堂在线观看| 亚洲国产人成在线观看69网站| 国产精品亚洲精品| 曰批全过程免费视频播放网站 | 人人揉揉香蕉大免费不卡| 亚洲国产精品久久久久秋霞影院| 全部免费毛片免费播放| 亚洲第一成年免费网站| 国产午夜无码视频免费网站 | 国产在线国偷精品免费看| 91大神在线免费观看| 亚洲A∨午夜成人片精品网站| 亚洲精品国产精品乱码不卡√| 久久综合亚洲鲁鲁五月天| 84pao国产成视频免费播放| 亚洲在成人网在线看| 成人免费看吃奶视频网站| 美女视频黄a视频全免费网站一区| 99re这里有免费视频精品| 亚洲字幕在线观看| 日韩免费无码一区二区视频| 免费的黄网站男人的天堂| 成年大片免费视频| 国产精品自拍亚洲| 成人啪精品视频免费网站| 国产亚洲精品成人久久网站| 国产亚洲精久久久久久无码AV| 久久久久久AV无码免费网站| 亚洲精品美女久久久久99| 131美女爱做免费毛片| 亚洲av乱码一区二区三区按摩| 亚洲精品无码专区2| 一级毛片免费毛片一级毛片免费| 国产精品亚洲片夜色在线| 免费人成视网站在线观看不卡| 免费萌白酱国产一区二区三区| 丁香婷婷亚洲六月综合色| 亚洲精品无码久久不卡| 亚洲毛片免费观看| 一级一片免费视频播放| 亚洲男人第一无码aⅴ网站|