先来看一下
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()); }}
结果是什么:直接报错
ConcurrentModificationException
先看一下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()); } }
第三种解决办法:增强for
for(String x:list){ if(x.equals("del")){ list.remove(x); } }
第四种解决办法:iterator遍历
Iterator<String> it = list.iterator(); while(it.hasNext()){ String x = it.next(); if(x.equals("del")){ it.remove(); } }
此问题,本人仅在remove对象时发现到此错误。当list里面是基本类型数据时并没有发生以上问题。在此记好。