<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://www.tkk7.com/Files/sitinspring/ConcurrentModificationTest20071203210937.rar

    posted on 2007-12-03 21:04 sitinspring 閱讀(1878) 評論(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://www.tkk7.com)原創,轉載請注明出處.
    主站蜘蛛池模板: 日韩一级视频免费观看| 亚洲最大激情中文字幕| 国产无遮挡又黄又爽免费视频| 久久亚洲精品无码观看不卡| 亚洲成人免费电影| jizz免费一区二区三区| 免费一本色道久久一区| 亚洲性猛交XXXX| 国产成人人综合亚洲欧美丁香花 | 伊人婷婷综合缴情亚洲五月| 又硬又粗又长又爽免费看| 免费99精品国产自在现线| 国产av天堂亚洲国产av天堂| 黄色a级片免费看| 久久精品免费一区二区喷潮| 77777亚洲午夜久久多喷| 222www免费视频| 亚洲AV永久无码精品一百度影院| 豆国产96在线|亚洲| 国产精品亚洲综合专区片高清久久久| 中国精品一级毛片免费播放| mm1313亚洲精品国产| 亚洲精品无码专区在线播放| 无码区日韩特区永久免费系列 | 亚洲综合在线一区二区三区| 91精品全国免费观看含羞草| 亚洲AV无码第一区二区三区| 免费v片在线观看视频网站| 亚洲Av无码精品色午夜 | 全免费A级毛片免费看网站| 亚洲毛片免费观看| 777爽死你无码免费看一二区| 亚洲国产最大av| 中文字幕不卡亚洲| 91精品免费国产高清在线| 黄色片网站在线免费观看| 亚洲AV日韩AV天堂一区二区三区| 国产99视频精品免费专区| 亚洲视频精品在线| 免费能直接在线观看黄的视频| 亚洲爆乳无码专区www|