点击上方 "程序员小乐"关注, 星标或置顶一起成长
每天凌晨00点00分, 第一时间与你相约
每日英文
All problems, and ultimately is a matter of time. All the worry, in fact is a bother.
一切问题,最终都是时间问题。一切烦恼,其实都是自寻烦恼。
每日掏心话
累了,那就停下来,拍一拍灰尘,让心灵重归洁净。昨天是今天的历史;今天是明天的历史;今天也是昨天的历史;明天也是今天的历史。
来自:Alice_qixin | 责编:乐乐
链接:blog.csdn.net/Alice_qixin/article/details/80256882
程序员小乐(ID:study_tech) 第 916 次推文 图源:百度往日回顾:真赞!IDEA中这么玩MyBatis,让编码速度飞起!
正文
先来看一下下面的样例是否符合你的问题场景
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里面是基本类型数据时并没有发生以上问题。在此记好。仅供参考
欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。欢迎加入程序员小乐技术交流群,在后台回复“加群”或者“学习”即可。
猜你还想看
Class.forName 和 ClassLoader 到底有啥区别?
关注订阅号「程序员小乐」,收看更多精彩内容
嘿,你在看吗?