Java循环中remove方法的使用
首先看下如下代码
public class Test
{
public static void main(String[] args)
{
List<String> ll = new ArrayList();
ll.add("1");
ll.add("2");
ll.add("3");
ll.add("4");
ll.add("5");
ll.add("6");
for (String value : ll)
{
if ("3".equals(value))
{
ll.remove(value);
}
}
System.out.println(ll);
}
}
目测打印的结果应该是[1, 2, 4, 5, 6],但运行的时候报ConcurrentModificationException
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at com.model.proxy.Test.main(Test.java:17)
原因
对于for(),java 虚拟机会将其翻译成Iterator迭代器,
java编译器中含有:hasNext()函数,而hasNext()函数中含有:size()函数,这意味着list数组的大小是动态生成的,它是使用index!=size()来判定是否有下一个元素的,理论上只有最后元素才回返回false,其它元素都会返回true,一旦返回了true就会调用next,这样在调用next的过程中就会调用concurrentExceptions,在for()中,不容许调用remove()函数。这也就解释了,删除倒数第二个数,不会导致报错,因为在判断倒数第二个数的时候,index!=size直接返回false,这样没有next
,也就不存在next的调用了。
解决方案
一.比较笨的一个方法,再新建一个list,将需要删除的元素放到新建的list中,然后调用原来list的removeAll()方法
public class Test
{
public static void main(String[] args)
{
List<String> ll = new ArrayList();
List<String> l = new ArrayList();
ll.add("1");
ll.add("2");
ll.add("3");
ll.add("4");
ll.add("5");
ll.add("6");
for (String value : ll)
{
if ("3".equals(value))
{
l.add(value);
}
}
ll.removeAll(l);
System.out.println(ll);
}
}
二.使用迭代器的remove()方法
public class Test
{
public static void main(String[] args)
{
List<String> ll = new ArrayList();
ll.add("1");
ll.add("2");
ll.add("3");
ll.add("4");
ll.add("5");
ll.add("6");
Iterator it = ll.iterator();
while(it.hasNext()){
String value = (String)it.next();
if("3".equals(value)){
it.remove();
}
}
System.out.println(ll);
}
}