添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

此时,一般都不会出问题,直接 remove(key)

2. map集合遍历删除多个

此时,若不注意往往容易出现问题,出现 ConcurrentModificationException

为什么呢?

  • 使用iterator迭代删除 时没有问题的,在每一次迭代时都会调用hasNext()方法判断是否有下一个,是允许集合中数据增加和减少的。

  • 使用forEach删除时 ,会报错ConcurrentModificationException,因为在forEach遍历时,是不允许map元素进行删除和增加。

所以,遍历删除map集合中元素时,必须使用迭代iterator

3. 案例

有如下集合:

Map<String, Integer> map=new HashMap<>();
    map.put("张三",22);
    map.put("李四",25);
    map.put("王五",33);
    map.put("赵六",28);
    map.put("田七",25);
    map.put("李思",25);
    map.put("李嘉欣",25);

需求:删除名字(即key)中包含“李”的元素

使用forEach时:

Set<Entry<String, Integer>> set=map.entrySet();
for (Entry<String, Integer> entry : set) {
    String name=entry.getKey();
    System.out.println(name);
    System.out.println(name.contains("李"));
    if(name.contains("李")){
        map.remove(name);

会报如下异常:

使用iterator时,一切正常

特别注意:删除时不能使用map.remove(key),否则也报ConcurrentModificationException

只能使用iterator.remove

Set<Entry<String, Integer>> set=map.entrySet();
Iterator<Entry<String, Integer>> iterator=set.iterator();
while(iterator.hasNext()){
    Entry<String, Integer> entry=iterator.next();
    String name=entry.getKey();
    if(name.contains("李")){
    //特别注意:不能使用map.remove(name)  否则会报同样的错误
        iterator.remove();

解释:Iterator.remove()是删除最近(最后)使用next()方法的元素。
从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。

完成代码:

package map遍历和删除;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/*map集合遍历删除*/
public class Test2 {
    public static void main(String[] args) {
        //key=name value=age
        Map<String, Integer> map=new HashMap<>();
        map.put("张三",22);
        map.put("李四",25);
        map.put("王五",33);
        map.put("赵六",28);
        map.put("田七",25);
        map.put("李思",25);
        map.put("李嘉欣",25);
        //单个删除删--remove  
        map.remove("张三");
        for(Map.Entry<String, Integer> entry:map.entrySet()){
            System.out.println(entry.getKey()+"="+entry.getValue());
        //需求:删除名字(即key)中包含“李”的元素
        /*分析:
         *  1.此时直接map.remove(key)就不符合要求了,必须进行遍历删除
         *  2.通常map集合遍历就两种方式,一个foreach和iterator
        Set<Entry<String, Integer>> set=map.entrySet();
        /*for (Entry<String, Integer> entry : set) {
            String name=entry.getKey();
            System.out.println(name);
            System.out.println(name.contains("李"));
            if(name.contains("李")){
                map.remove(name);
        Iterator<Entry<String, Integer>> iterator=set.iterator();
        while(iterator.hasNext()){
            Entry<String, Integer> entry=iterator.next();
//          String name=entry.getKey();
            String name=entry.getKey();
            int value=entry.getValue();
            if(name.contains("李")){
                //特别注意:不能使用map.remove(name)  否则会报同样的错误
                iterator.remove();
        System.out.println();
        for (Entry<String, Integer> entry : set) {
            System.out.println("姓名:"+entry.getKey()+",年龄:"+entry.getValue());
                                    集合遍历过程中删除元素报错ConcurrentModificationException(并发修改异常)
今天敲代码时遇到一个异常,代码如下:
List<Integer> list = new ArrayList<>();
list:[50, 42, 56, 76, 62, 38, 42, 98, 66, 91, 53, 56, 97, 61, 33, 26, 97, 45]        
//遍历list去除奇数
Iterator<Integer> iterator 
                                    前段时间,同事在代码中KW扫描的时候出现这样一条:上面出现这样的原因是在使用foreach对HashMap进行遍历时,同时进行put赋值操作会有问题,异常ConcurrentModificationException。于是帮同简单的看了一下,印象中集合类在进行遍历时同时进行删除或者添加操作时需要谨慎,一般使用迭代器进行操作。于是告诉同事,应该使用迭代器Iterator来对集合元素进行操作。同事问我为什么?这一下子把我问蒙了?对啊,只是记得这样用不可以,但是好像自己从来没有细究过为什么?
异常情况举例
只要抛出出现异常,可以肯定的是代码一定有错误的地方。先来看看都有哪些情况会出现ConcurrentModificationException异常,下面以ArrayList的remove操作进行举例:
使用的数据集合:
List myList = new ArrayList();
myList.add( “1”);     myList.add( “2
                                    出现的原因:jdk5.0以上的for-each也是利用内部的iterator遍历集合的(跟以前的iterator一样)获得的Iterator是一个内部类产生的迭代器,这个迭代器在调用next方法时,会检查列表是否被修改过,如果被修改过,就会抛出ConcurrentModificationException异常。进一步说,当使用 fail-fast iterator 对 Collection 
                                    不能直接在 Map 的 for 循环中使用 remove 方法,会抛出 ConcurrentModificationException 异常,应使用迭代器中的 remove 方法删除元素。
1.直接遍历
Map<String,Object> remindTimeAndUser= new HashMap<>();
	for(Map.Entry<String,Object> entry : remindTimeAndUser.entrySet()) {
	   String key = entry.getKey();
	   List<String> userIds= (List<String>) entry.
                                    有一个应用场景,需要多线程访问同一HashMap,其中线程一只作遍历查询,线程二进行添加、修改或删除,在实际使用过程中遇到了ConcurrentModificationException的并发修改异常。
                                    文章目录1. 前言2. 回顾下ArrayList3. HashMap3.1 为什么HashMap是非线程安全的?3.2  HashMap迭代期间,可能引起ConcurrentModificationException异常3.3 使用ConcurrentHashMap替代HashMap3.3 ConcurrentHashMap迭代期间能执行remove等操作吗
1. 前言
我们之前写过关于ArrayList的线程安全相关的文章《java.util.ConcurrentModificationException
                                    (并发修改异常)通常在使用迭代器(Iterator遍历集合的过程中,同时对集合进行了结构性修改(例如添加、删除元素)时抛出。选择适当的集合类和迭代方式,以满足你的并发需求。在一些特定场景下,可能需要权衡快速失败与弱一致性的选择。在多线程环境中,要注意对集合的并发修改问题,可以使用同步机制或使用并发集合类。确保在进行集合的迭代操作时,避免直接修改集合结构,使用迭代器的。方法或使用并发安全的集合类,以避免。