java中在for循环中remove元素时的陷阱

java.util.ConcurrentModificationException

如果删空了,会报上面这个异常

输出结果如下:
remove前集合数据:a,a,b,a,a,

remove后集合数据:a,b,a,

为什么会出现这种情况?原因是集合的大小是动态变化的,在删除第1个值为“a”的元素后,集合的大小已经发生了改变,但是i的值在删除后继续执行了加1操作,此时已经跳过了“a”元素后的元素(即原集合中第2个“a”元素)。

如下删除集合中值为“a”的元素时:

import java.util.*;

public class Demo {

    public static void main(String[] args) throws Exception {

        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("a");
        list.add("a");

        System.out.print("remove前集合数据:");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i)+",");
        }

        //删除集合中值为“1”的数据
        for (int i = 0; i < list.size(); i++) {
            if ("a".equals(list.get(i))) {
                list.remove(i);
            }
        }

        System.out.println("");
        System.out.print("remove后集合数据:");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i)+",");
        }
    }
}

解决方法:

1、在执行完remove操作后,对i的值进行减1操作,即修改后的代码如下:

import java.util.*;

public class Demo {

    public static void main(String[] args) throws Exception {

        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("a");
        list.add("a");

        System.out.print("remove前集合数据:");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i)+",");
        }

        //删除集合中值为“a”的数据
        for (int i = 0; i < list.size(); i++) {
            if ("a".equals(list.get(i))) {
                list.remove(i);
                i--;
            }
        }

        System.out.println("");
        System.out.print("remove后集合数据:");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i)+",");
        }
    }
}
2、用迭代器的方式删除数据
import java.util.*;

public class Demo {

    public static void main(String[] args) throws Exception {

        List<String> list = new ArrayList<String>();
        list.add("a");
        list.add("a");
        list.add("b");
        list.add("a");
        list.add("a");

        System.out.print("remove前集合数据:");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i)+",");
        }

        //删除集合中值为“a”的数据
        Iterator<String> iter = list.iterator();
        while (iter.hasNext()) {
            String temp = iter.next();
            if ("a".equals(temp)) {
                iter.remove();
            }
        }

        System.out.println("");
        System.out.print("remove后集合数据:");
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i)+",");
        }
    }
}

原文地址:https://www.cnblogs.com/moonsoft/p/12310439.html

时间: 2024-10-24 12:31:39

java中在for循环中remove元素时的陷阱的相关文章

Java - List遍历、判断、删除元素时的陷阱

开发中,常有“遍历集合,依次判断是否符合条件,如符合条件则删除当前元素”的场景,有一些陷阱常犯. 漏网之鱼 import java.util.ArrayList; import java.util.List; public class ListTest_Unwork { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("1"

Java中对List集合内的元素进行顺序、倒序、随机排序的示例代码

1 import java.util.Collections; 2 import java.util.LinkedList; 3 import java.util.List; 4 5 public class Test { 6 7 List list = new LinkedList(); 8 public static void main(String[] args) { 9 List list = new LinkedList(); 10 for ( int i = 0 ; i < 9 ;

java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

是引用对象的地址值不能变,引用变量所指向的对象的内容是可以改变. final变量永远指向这个对象,是一个常量指针,而不是指向常量的指针. 例如:final StringBuffer sbu = new StringBuffer(“abc”); 在对其进行重新赋值 sbu = new StringBuffer(“”); 会出现编译错误,被final修饰的变量是不能被重新赋值的. sbu.append(“d”); 是可以编译通过的; final:最终.作为一个修饰符 1.可以修饰类.变量.函数. 2

Java中使用Jsoup抓取网页URL时出现中文汉字乱码的问题及解决办法

public static String readHtml(String myurl) { StringBuffer sb = new StringBuffer(""); URL url; try { url = new URL(myurl); BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(), "gbk")); String s = "";

在Java中导出word、excel格式文件时JSP页面头的设置

我们在JSP中往往会把一些表格里的东西需要导出到本地,一般都是导成word.excel格式的文件.这只需要在JSP页面头设置及在<head></head>标签中添加下面的代码: 导出为excel: <% response.setContentType("application/vnd.ms-excel;charset=UTF-8"); response.setHeader("Content-Disposition","atta

java中最常见的几种运行时异常,你get了吗?

NullPointerException (空指针异常) ClassCastException (类型强制转换异常) NumberFormatException (数字格式异常) NegativeArraySizeException (数组大小为负数异常) SecurityException (安全异常) BufferOverFlowException (缓冲区溢出异常) IndexOutofBoundsException (下标越界异常) 原文地址:https://www.cnblogs.co

java中的Stream流

java中的Stream流 说到Stream便容易想到I/O Stream,而实际上,谁规定"流"就一定是"IO流"呢?在Java 8中,得益于Lambda所带 来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊端. 一.引言 传统集合的多步遍历代码 几乎所有的集合(如 Collection 接口或 Map 接口等)都支持直接或间接的遍历操作.而当我们需要对集合中的元 素进行操作的时候,除了必需的添加.删除.获取外,典型的就是集合遍历.

java中的变量及其转换

java中的变量  变量或变数,是指没有固定的值,可以改变的数.变量以非数字的符号来表达,一般用拉丁字母.变量是常量的相反,变量的用处在于能一般化描述指令的方式. 从本质上讲,变量其实是内存中的一小块区域,使用变量名来访问这块区域,因此,每个变量使用前必须先要声明,然后必须填充内容,最后才能使用. 变量的分类  (1)按所属的数据类型划分:基本数据类型变量和引用数据类型变量 (2)按声明的位置划分:局部变量和全局变量(成员变量) 局部变量:方法或语句块内部定义的变量: 全局变量(成员变量):方法

java中outer的使用

outer多用于嵌套循环的情况 1 outer: 2 for (int i = 2 ; i <= 10 ; i++) 3 { 4 5 for (int j = 2 ; j <=10 ; j++) 6 { 7 8 if(i != 2 && j % i== 0) 9 { 10 continue outer; 11 } 12 } 13 System.out.println(i+n); 14 } 满足内层循环中if条件时需要跳出到外层循环,此时便需要使用outer,相当于goto.