前段时间做项目时需要对list数据做过滤,当时想到的是for循环和增强for循环,跑过的数据总是不对,以为逻辑的问题,搞了好久,后来网上看了下,发现是for循环和增强for循环的问题,必须使用迭代器删除符合条件的数据。网上给出的解释大同小异,并不是很清楚,所以今天总结一下,方便以后查看。
一.list三种遍历方式
1.for循环
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
for(int i = 0;i < list.size(); i++){
System.out.println(list.get(i));
}
2.增强for循环
List<String> list = new ArrayList<String>();
list.add("A");
list.add("A");
list.add("C");
list.add("D");
for(String name : list){
System.out.println(name);
}
3.使用迭代器遍历
List<String> list = new ArrayList<String>();
list.add("A");
list.add("A");
list.add("C");
list.add("D");
Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
以上三种就是我们常用遍历lis
二.遍历list并删除符合条件的数据
1.首先是我们最常见的for循环,直接上代码
List<String> list = new ArrayList<String>();
list.add("A");
list.add("A");
list.add("C");
list.add("D");
System.out.println(list.toString());
for(int i = 0;i < list.size(); i++){
String str = list.get(i);
if(str.equals("A")){
list.remove(i);
}
}
System.out.println(list.toString());
从代码中我们很容易看出来目的,从list中将A删掉(虽然真实数据不会出现这种AA的情况,只是举例说明for循环会出现删除数据不准确的情况),实际上运行程序后我们发现结果并不是我们想象的样子。
通过分析我们可以发现下次执行list.get(i)是应该取出第二个A进行判断,实际上第二个A并么有被渠道,因为执行list.remove()方法后,第二个A会对应的下表会变成0,C对应的下表会变成1,所以第二次遍历时取出的值是C,所以这样删除是有问题的。
2.增强for循环
List<String> list = new ArrayList<String>();
list.add("A");
list.add("A");
list.add("C");
list.add("D");
for(String name : list){
if(name.equals("A")){
list.remove(name);
}
}
System.out.println(list.toString());
运行直接抛异常java.util.ConcurrentModificationException,我们把判断条件换成C或D是就可以正常。
如果list没有多个符合删除条件的数据,即使有多个判断条件(比如判断等于B或者等于C时删除数据),使用for循环是可以的。而增强for循环,当list中没有多个附件删除条件的数据时且只有一个判断条件是,是可以使用的。当时如果用个遍历还要考虑这么多也太痛苦了,所以以上两种方式,即使是可以使用的也不推荐,推荐使用第三种遍历方式。
3.迭代器遍历
List<String> list = new ArrayList<String>();
list.add("A");
list.add("A");
list.add("C");
list.add("D");
Iterator<String> it = list.iterator();
while(it.hasNext()){
if(it.next().equals("A")){
it.remove();
}
}
System.out.println(list.toString());
使用这种方式无论什么样的数据,无论什么判断条件都可以,所以强烈推荐和我一样的菜鸟使用这种遍历。