原来一直没仔细想过java中for循环的删除问题,昨天写一道题时候发现输出结果跟想象不一样,debug时候发现了这个问题,写出来分享一下。
我们使用for循环遍历一个list的时候,有两种方法,一种是普通的从0到list.size(),然后依次get(),另一种是增强for循环,所有的资料上都说了增强for循环只能用来遍历元素,而不能用来删除和修改,那么,我们今天来做个实验探讨以下如何正确的删除元素。
我们先准备实验用的测试数据
List<String> list=new ArrayList<String>();
list.add("asdf");
list.add("bbb");
list.add("aaa");
list.add("acd");
list.add("da");
然后是两种for循环,在编译元素的时候,它们的作用是一样的,就不多说了。
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
for(String s:list){
System.out.println(s);
}
asdf
bbb
aaa
acd
da
上述为输出结果。
如果我们想要删除list中包含有字母a的元素,应该怎么做呢,首先想当然就是在用index遍历时判断该元素是否包含字符'a',如果包含的话则删除。否则继续循环,代码如下
for(int i=0;i<list.size();i++){
if(list.get(i).contains("a")){
list.remove(i);
}
}
你可能觉得这个并没有什么难的,直接删除就可以了,那么我们来看看结果:
bbb
acd
acd没有被删掉!!!!!!是不是很神奇。
我们debug进去看一下原因。当i=0时删除第一个元素,此时list中元素为
[bbb, aaa, acd, da],i要进行加1操作变为1,则忽略了"bbb"元素!!!,然后删除"aaa"之后,list中元素为
[bbb, acd, da],此时i加1变为了2,忽略掉了"acd",必然与结果不一样了。那么我们应该如何避免这个问题呢?方法就是在删除完元素之后,将索引i减1,使它保持到原位置。这样就能输出正确结果了~代码如下:
for(int i=0;i<list.size();i++){
if(list.get(i).contains("a")){
list.remove(i);
i--;
}
}
结果:
bbb
我们再来看看增强for循环的删除
for(String s:list){
if(s.contains("a")){
list.remove(s);
}
}
因为list集合删除元素可以用索引和指针两种方式,我们自然想到了用list.remove(Object)方法了,运行以下,发现报了下面的错。
Exception in thread "main" java.util.ConcurrentModificationException
这是使用iterator()的一个错误,有兴趣的可以自行百度一下~