遍历Map的时候删除map中的元素,报异常Exception in thread "main" java.util.ConcurrentModificationException

简单的例子

package collection;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class TestRemoveMap {
	static Map<String, Set<String>> map = new HashMap<String, Set<String>>();
	static{
		Set<String> set = new HashSet<String>();
		map.put("company", set);
		set.add("zte");
		set.add("huawei");
		set.add("ericcson");
		
		Set<String> set1 = new HashSet<String>();
		map.put("food", set1);
		set1.add("rice");
				
		Set<String> set2 = new HashSet<String>();
		map.put("people", set2);
		set2.add("zhangsan");
		set2.add("lisi");
		
		Set<String> set3 = new HashSet<String>();
		map.put("aa", set3);
		set3.add("bb");
		set3.add("vv");
		
		Set<String> set4 = new HashSet<String>();
		map.put("dd", set4);
		set4.add("ee");
		set4.add("ff");
		
		Set<String> set5 = new HashSet<String>();
		map.put("co1mpany", set5);
		set5.add("zte");
		set5.add("huawei");
		set5.add("ericcson");
		
		Set<String> set6 = new HashSet<String>();
		map.put("compan7y", set);
		set6.add("zte");
		set6.add("huawei");
		set6.add("ericcson");
		
		Set<String> set7 = new HashSet<String>();
		map.put("compa7ny", set);
		set7.add("zte");
		set7.add("huawei");
		set7.add("ericcson");
	}
	public static void removeMapByMeaning(String value){
		for(Entry<String, Set<String>> entry : map.entrySet()){
			if(entry.getValue().contains(value)){
				if(entry.getValue().size()==1){
					map.remove(entry.getKey());
				}else{
					entry.getValue().remove(value);
				}
				
			}
		}
		
	}
	public static void main(String[] args) {
		
		removeMapByMeaning("lisi");
		System.out.println(map);
		removeMapByMeaning("rice");
		System.out.println(map);
		removeMapByMeaning("ff");
		System.out.println(map);
		
	}
}
输出:
{aa=[bb, vv], dd=[ee, ff], company=[huawei, zte, ericcson], people=[zhangsan], co1mpany=[huawei, zte, ericcson], food=[rice], compan7y=[huawei, zte, ericcson], compa7ny=[huawei, zte, ericcson]}
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
	at java.util.HashMap$EntryIterator.next(HashMap.java:1471)
	at java.util.HashMap$EntryIterator.next(HashMap.java:1469)
	at collection.TestRemoveMap.removeMapByMeaning(TestRemoveMap.java:56)
	at collection.TestRemoveMap.main(TestRemoveMap.java:72)

原理分析:for(Entry<String, Set<String>> entry : map.entrySet())这种for each循环,原理还是使用的迭代器iterator

1.首先看下迭代器的实例化

 HashIterator() {
            expectedModCount = modCount;
            Node<K,V>[] t = table;
            current = next = null;
            index = 0;
            if (t != null && size > 0) { // advance to first entry
                do {} while (index < t.length && (next = t[index++]) == null);
            }
        }
会将一个modCount赋值给一个expectedModCount变量,modCount的含义就是map被修改的次数,增加,删除元素都会修改modCount的值,取元素和修改元素的时候不变。

2.循环中取下一个元素的代码(next()函数)

final class EntryIterator extends HashIterator
        implements Iterator<Map.Entry<K,V>> {
        public final Map.Entry<K,V> next() { return nextNode(); }
    }
直接了nextNode()函数

 final Node<K,V> nextNode() {
            Node<K,V>[] t;
            Node<K,V> e = next;
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (e == null)
                throw new NoSuchElementException();
            if ((next = (current = e).next) == null && (t = table) != null) {
                do {} while (index < t.length && (next = t[index++]) == null);
            }
            return e;
        }
看到了该异常的出处,因为在遍历的时候,增删map本身的元素会修改countMod的值。

正确的删除方式是使用迭代器的remove函数来删除map中的元素。

package collection;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class TestRemoveMap {
	static Map<String, Set<String>> map = new HashMap<String, Set<String>>();
	static{
		Set<String> set = new HashSet<String>();
		map.put("company", set);
		set.add("zte");
		set.add("huawei");
		set.add("ericcson");
		
		Set<String> set1 = new HashSet<String>();
		map.put("food", set1);
		set1.add("rice");
				
		Set<String> set2 = new HashSet<String>();
		map.put("people", set2);
		set2.add("zhangsan");
		set2.add("lisi");
		
		Set<String> set3 = new HashSet<String>();
		map.put("aa", set3);
		set3.add("bb");
		set3.add("vv");
		
		Set<String> set4 = new HashSet<String>();
		map.put("dd", set4);
		set4.add("ee");
		set4.add("ff");
		
		Set<String> set5 = new HashSet<String>();
		map.put("co1mpany", set5);
		set5.add("zte");
		set5.add("huawei");
		set5.add("ericcson");
		
		Set<String> set6 = new HashSet<String>();
		map.put("compan7y", set);
		set6.add("zte");
		set6.add("huawei");
		set6.add("ericcson");
		
		Set<String> set7 = new HashSet<String>();
		map.put("compa7ny", set);
		set7.add("zte");
		set7.add("huawei");
		set7.add("ericcson");
	}
	public static void removeMapByMeaning(String value){
		for(Entry<String, Set<String>> entry : map.entrySet()){
			if(entry.getValue().contains(value)){
				if(entry.getValue().size()==1){
					map.remove(entry.getKey());
				}else{
					entry.getValue().remove(value);
				}
				
			}
		}
		
	}
	
	public static void rightRemoveMap(String value){
		Iterator<Entry<String, Set<String>>> iterator = map.entrySet().iterator();
	     while(iterator.hasNext()){
	    	 Entry<String, Set<String>> entry = iterator.next();
	    	 if(entry.getValue().contains(value)){
					if(entry.getValue().size()==1){
						iterator.remove();
					}else{
						
						Iterator<String> iterator2 = entry.getValue().iterator();
						while(iterator2.hasNext()){
							if(value.equals(iterator2.next())){
								iterator2.remove();
							}
						}
					}
					
				}
	     }
	}
	public static void main(String[] args) {
		
		rightRemoveMap("lisi");
		System.out.println(map);
		rightRemoveMap("rice");
		System.out.println(map);
		rightRemoveMap("ff");
		System.out.println(map);
		
	}
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值