list - 删除元素 ConcurrentModificationException

发布时间 2023-05-24 13:26:00作者: shirleyLee

 

前天看了公众号,说是三年开发都不会删除元素,看了一眼,没想到第二天就用上了........而我也是那个菜鸟哈哈哈哈哈哈.........记录一下吧

 

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");

    for (String s : list) {
        if (s.equals("1")) {
            list.remove(s);
        }
    }

    System.out.println(list);
}

移除元素的时候想到的就是List的remove()方法,然后出现报错  java.util.ConcurrentModificationException

 

原因是,将上面代码转变为字节码,会发现for循环在执行的时候实际使用的是Iterator,核心方法是hasNext()和next()

而这两个方法的底层原理

 

在使用next()时,调用checkForComodification()方法

next()在获取下一个元素时,比较modCount 和 expectedModCount 两个值

在使用remove时,modCount++,第二次再remove的时候值不相等就会抛错

 

 

 解决方法:

第一种-----使用Iterator的remove()方法

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");

    Iterator<String> iterator = list.iterator();
    while (iterator.hasNext()) {
        String s = iterator.next();
        if (s.equals("1")) {
            iterator.remove();
        }
    }

    System.out.println(list);
}

 底层:每次remove会重新赋值

 

 第二种-------for循环正序(修改下标)

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");

    for (int i = 0; i < list.size(); i++) {
        String item = list.get(i);
        if (item.equals("1")) {
            list.remove(item); 
            i = i - 1;
        }
    }

    System.out.println(list);
}

 

 第三种---------for循环倒序

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    list.add("1");
    list.add("2");
    list.add("3");

    for (int i = list.size() - 1; i >= 0; i--) {
        String item = list.get(i);
        if (item.equals("1")) {
            list.remove(item); 
            i = i - 1;
        }
    }

    System.out.println(list);
}

 

 最后可以使用stream流

public static void main(String[] args) {
 List<String> list = new ArrayList();
    list.add("1");
    list.add("2");
    list.add("3");
    list = list.stream().filter(e -> !e.startsWith("1")).collect(Collectors.toList());
    System.out.println(list);
}