正确处理移除list中数据

本文探讨了在Java中遍历集合时直接修改引发的ConcurrentModificationException异常,并提供了使用Iterator正确移除元素的方法。

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

首先大家先看一段代码:

 

public static void main(String[] args) {

      List<String> listStr = new ArrayList<String>();
      listStr.add("1");
      listStr.add("2");
      listStr.add("3");
      listStr.add("4");
      listStr.add("5");

     System.out.println("listStr.size:::"+listStr.size());  

 

      for(String str:listStr){
         if("3".equals(str)){
             listStr.remove(str);  

         }
      }


      System.out.println("listStr.size:::"+listStr.size());

 

现象:

      该程序会抛出一个  java.util.ConcurrentModificationException异常。

分析:

      对 Collection 或 Map 进行迭代操作过程中尝试直接修改 Collection / Map 的内容时,会抛出java.util.ConcurrentModificationException 异常。 因为在修改数据时不能同步原有list中数据,当下一次循环时找不到数据。

 

解决办法:

       Iterator 在工作的时候是不允许被迭代的对象被改变的,使用 Iterator 本身的方法 remove() 来删除对
象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。

 

改后代码:

      

public static void main(String[] args) {

      List<String> listStr = new ArrayList<String>();
      listStr.add("1");
      listStr.add("2");
      listStr.add("3");
      listStr.add("4");
      listStr.add("5");
  

 

      System.out.println("listStr.size:::"+listStr.size());

 

      Iterator<String> ite = listStr.iterator();
      while(ite.hasNext()){
          String str = (String)ite.next();
          if("3".equals(str)){
             ite.remove();
          }
      }


      System.out.println("listStr.size:::"+listStr.size());

}

 

补充:

      或许有人可能会问如果我不用增强for循环,直接用.get(index)方法会不会报错?

   代码如下:

      for(int i = 0 ; i < listStr.size(); i++){
           if("3".equals(listStr.get(i))){
               listStr.remove(i);
           }
      }

  现象:

        listStr.size:::5
        listStr.size:::4

        大家可以看到通过list的下表索引来修改list数据是不会出错的。

  分析:

       大家可以这样认为:通过所引来循环时,jvm记录的是所引值,当移除当前对象后,其他元素的索引号不会同步改变。下次循环仍可以找到对应数据。而增强for循环,记录的是当前对象,当下次循环时,会先找到该对象,然后游标向下移,这时候找不到对象所以结果会混乱。

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值