使用List中的remove方法遇到数组越界

简介: 使用List中的remove方法遇到数组越界

先来看一下下面的样例是否符合你的问题场景

 

list中根据判断条件符合的就remove掉一个数据

 

 public static void main(String[] args) {
        List<CaseHead> list=new ArrayList<CaseHead>();
        CaseHead caseHead1=new CaseHead();
        caseHead1.setCaseid("a");
        CaseHead caseHead2=new CaseHead();
        caseHead2.setCaseid("b");
        CaseHead caseHead3=new CaseHead();
        caseHead3.setCaseid("c");
        CaseHead caseHead4=new CaseHead();
        caseHead4.setCaseid("d");
        CaseHead caseHead5=new CaseHead();
        caseHead5.setCaseid("e");
        list.add(caseHead1);
        list.add(caseHead2);
        list.add(caseHead3);
        list.add(caseHead4);
        list.add(caseHead5);
 
 
        List<String> list2=new ArrayList<String>();
        list2.add("a");
        list2.add("b");
 
        for (int i = 0; i < list.size(); i++) {
            String caseid=list.get(i).getCaseid();
            for (int j = 0; j <list2.size() ; j++) {
                String l=list2.get(j);
                if (caseid.equals(l)){
                    list.remove(i);
                }
            }
 
 
        }
 
        for (int a = 0; a < list.size(); a++) {
            System.out.println(list.get(a).getCaseid());
        }}

 

结果是什么?

 

结果是一下。根据以上代码,希望得到的结果是 cde 但是运行结果是bcde那么问题来了为什么会得到一下结果呢

 

 

 

先看一下list remove的源码

 

// 删除ArrayList指定位置的元素
    public E remove(int index) {
        RangeCheck(index);//检查index是否超出list大小范围,否则抛出异常
        modCount++;
        E oldValue = (E) elementData[index];//elementData是实现list的数组
        int numMoved = size - index - 1;//当执行删除操作是后面的元素全部向前面移动一位
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                 numMoved);
        elementData[--size] = null;
        return oldValue;
    }
    // 删除ArrayList的指定元素
    public boolean remove(Object o) {
        if (o == null) {
          for (int index = 0; index < size; index++)
             if (elementData[index] == null) {
                 fastRemove(index);
                return true;
            }
        } else {
            for (int index = 0; index < size; index++)
              if (o.equals(elementData[index])) {
                  fastRemove(index);
                  return true;
              }
        }
        return false;
   }
  //快速删除第index个元素
  private void fastRemove(int index) {
        modCount++;  
        int numMoved = size - index - 1;  
        if (numMoved > 0)  
            System.arraycopy(elementData, index+1, elementData, index,  
                             numMoved);  
        elementData[--size] = null; 
   } 

 

源码可知,List在删除指定位置的对象时,执行删除操作是后面的元素全部向前面移动一位

 

因为,当你remove掉一个对象时,list的就少了一个 index 0的被remove了,之前index 1的数据就自动变为index 0了。arrayList是有顺序数组,从0开始。如果从前开始删除实际上就相当于跳着删除了。

 

解决办法1:

 

每次删除之后i--自动返回到上一个index开始

 

    public static void main(String[] args) {
        List<CaseHead> list=new ArrayList<CaseHead>();
        CaseHead caseHead1=new CaseHead();
        caseHead1.setCaseid("a");
        CaseHead caseHead2=new CaseHead();
        caseHead2.setCaseid("b");
        CaseHead caseHead3=new CaseHead();
        caseHead3.setCaseid("c");
        CaseHead caseHead4=new CaseHead();
        caseHead4.setCaseid("d");
        CaseHead caseHead5=new CaseHead();
        caseHead5.setCaseid("e");
        list.add(caseHead1);
        list.add(caseHead2);
        list.add(caseHead3);
        list.add(caseHead4);
        list.add(caseHead5);
 
 
        List<String> list2=new ArrayList<String>();
        list2.add("a");
        list2.add("b");
 
        for (int i = 0; i < list.size(); i++) {
            String caseid=list.get(i).getCaseid();
            for (int j = 0; j <list2.size() ; j++) {
                String l=list2.get(j);
                if (caseid.equals(l)){
                    list.remove(i);
                    i--;
                }
            }
 
 
        }
 
        for (int a = 0; a < list.size(); a++) {
            System.out.println(list.get(a).getCaseid());
        }
}

 

第二种解决方法

 

倒着删除从后往前遍历删除,从index大的往index小的删

 

    public static void main(String[] args) {
        List<CaseHead> list=new ArrayList<CaseHead>();
        CaseHead caseHead1=new CaseHead();
        caseHead1.setCaseid("a");
        CaseHead caseHead2=new CaseHead();
        caseHead2.setCaseid("b");
        CaseHead caseHead3=new CaseHead();
        caseHead3.setCaseid("c");
        CaseHead caseHead4=new CaseHead();
        caseHead4.setCaseid("d");
        CaseHead caseHead5=new CaseHead();
        caseHead5.setCaseid("e");
        list.add(caseHead1);
        list.add(caseHead2);
        list.add(caseHead3);
        list.add(caseHead4);
        list.add(caseHead5);
 
 
        List<String> list2=new ArrayList<String>();
        list2.add("a");
        list2.add("b");
 
        for (int i = list.size()-1; i >= 0; i--) {
            String caseid=list.get(i).getCaseid();
            for (int j = 0; j <list2.size() ; j++) {
                String l=list2.get(j);
                if (caseid.equals(l)){
                    list.remove(i);
 
                }
            }
 
 
        }
 
        for (int a = 0; a < list.size(); a++) {
            System.out.println(list.get(a).getCaseid());
        }
}

 

 

 

此问题,本人仅在remove对象时发现到此错误。当list里面是基本类型数据时并没有发生以上问题。在此记好。

相关文章
|
4天前
如何实现数组和 List 之间的转换?
如何实现数组和 List 之间的转换?
|
4天前
|
开发者 Python
【亮剑】Python中`List.append()`方法不起作用的原因及解决方案
【4月更文挑战第30天】本文探讨了Python中`List.append()`方法不起作用的原因及解决方案。问题可能源于变量作用域、可变类型与不可变类型混淆、函数内的局部变量、错误的赋值操作或并发修改。解决方法包括检查变量、确保正确操作列表、使用`global`关键字、避免错误赋值和采用同步机制处理并发问题。理解这些问题对于编写健壮的Python代码至关重要。
|
4天前
|
Java API
【亮剑】三种有效的方法来删除List中的重复元素Java的List
【4月更文挑战第30天】本文介绍了三种Java中删除List重复元素的方法:1) 使用HashSet,借助其不允许重复值的特性;2) 利用Java 8 Stream API的distinct()方法;3) 对自定义对象重写equals()和hashCode()。每种方法都附带了代码示例,帮助理解和应用。
|
4天前
|
存储 索引 Python
多数pythoneer只知有列表list却不知道python也有array数组
多数pythoneer只知有列表list却不知道python也有array数组
27 0
|
4天前
|
Java
Java中拷贝list数组如何实现
Java中拷贝list数组如何实现
13 0
|
4天前
List中的remove方法遇到报错不能删除以及四种解决办法点赞收藏
List中的remove方法遇到报错不能删除以及四种解决办法点赞收藏
21 0
|
4天前
|
Java
JAVA——List中剔除空元素(null)的三种方法汇总
JAVA——List中剔除空元素(null)的三种方法汇总
|
4天前
|
存储 安全 Java
java集合框架及其特点(List、Set、Queue、Map)
java集合框架及其特点(List、Set、Queue、Map)
|
4天前
|
存储 安全 算法
Java一分钟之-Java集合框架入门:List接口与ArrayList
【5月更文挑战第10天】本文介绍了Java集合框架中的`List`接口和`ArrayList`实现类。`List`是有序集合,支持元素重复并能按索引访问。核心方法包括添加、删除、获取和设置元素。`ArrayList`基于动态数组,提供高效随机访问和自动扩容,但非线程安全。文章讨论了三个常见问题:索引越界、遍历时修改集合和并发修改,并给出避免策略。通过示例代码展示了基本操作和安全遍历删除。理解并正确使用`List`和`ArrayList`能提升程序效率和稳定性。
11 0
|
4天前
|
存储 安全 Java
【JAVA基础篇教学】第八篇:Java中List详解说明
【JAVA基础篇教学】第八篇:Java中List详解说明
http://www.vxiaotou.com