利用java迭代器Itetator遍历并删除HashMap中的元素问题

本文探讨了在使用HashMap迭代时,删除元素会导致的并发修改异常问题,并提供了三个解决方案来避免此类异常。解决方案包括:1. 两层循环嵌套更新迭代器,时间复杂度过高;2. 使用HashMap副本的迭代器遍历,空间复杂度增加;3. 利用迭代器的remove方法直接删除元素,简化操作。文章旨在提供有效的错误处理策略,提高程序健壮性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自 http://www.blogjava.net/hwpok/archive/2011/11/05/362723.html

问题:
下面的代码试图利用
HashMap的Iterator对象遍历该HashMap并删除满足条件的元素(比如超时的元素),但会抛出java.util.ConcurrentModificationException异常
    public static void main(String[] args)
        
        HashMap<String, String> hs=new HashMap();    
        hs.put("p1", "1");
        hs.put("p2", "1");
        hs.put("p3", "1");
        hs.put("p4", "1");
        hs.put("p5", "1");
        hs.put("p6", "1");       
        Iterator it=hs.keySet().iterator();      
        while(it.hasNext())
        {
            String str=(String)it.next();               
            System.out.println(hs);   

             //逻辑处理.........         
             .............
            hs.remove(str);      
         
}
    原因应该
hs.remove(str)后,it内容没变,并且it里的指针列表又重新排序,所以只要确保删除任一元素后,it保持同步更新即可:
    解决方案一:
删除任一元素后,it保持同步更新
    ............
      
Iterator it=hs.keySet().iterator();   
        while(it.hasNext())
        {
            it=hs.keySet().iterator();  
            String str=(String)it.next();               
            System.out.println(hs);   

             //逻辑处理.........         
             .............
            hs.remove(str);      
         

    ...........
    这样的时间复杂度明显太大(两层循环嵌套)
    解决方案二:
由于删除元素时,hs的iterator对象也重新排序,所以只要用hs的一个副本hsBack
Uackp的iterator去遍历hs即可,这样在删除hs元素时iterator就不会重排了(因为删除的是hs的元素,而不是该iterator所属的
hsBackUackp
...................
        hsBackUp=(HashMap<String, String>)hs.clone();
        Iterator it=hsBackUp.keySet().iterator();
        System.out.println(hsBackUp);
        while(it.hasNext())
        {
            String str=(String)it.next();               
            System.out.println(hs);               
            hs.remove(str);       
         
.....................
    这样虽然时间复杂度小了(只有一层循环),可是空间复杂度大了(多了一个hashmap的拷贝);
    查阅api文档和相关资料后,原来iterator对象有一remove方法:
void remove()       

    Removes from the underlying collection the last element returned by the

 iterator (optional operation).  This method can be called only once per

 call to next.  The behavior of an iterator is unspecified if

 the underlying collection is modified while the iteration is in

 progress in any way other than by calling this method.

于是有下面的改进:

    解决方案三:

..............................

Iterator it=hs.keySet().iterator();      

        while(it.hasNext())

        {

            String str=(String)it.next();               

            System.out.println(hs);               

            it.remove();  

        }   

..............................

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值