1、Exception in thread "main" java.util.ConcurrentModificationException
先来看一个程序
public class TestFor { public static void oldFor(List<String> list) { for (int i = 0; i < list.size(); i++) { String str = list.get(i); if (str.equals("2")) { list.remove(i); } } } public static void newFor(List<String> list) { for (String str : list) { if (str.equals("2")) { list.remove(str); } } } public static void main(String[] args) { List<String> list1 = new ArrayList<String>(); list1.add("1"); list1.add("2"); list1.add("3"); list1.add("4"); list1.add("5"); list1.add("6"); oldFor(list1); System.out.println(list1); List<String> list2 = new ArrayList<String>(); list2.add("1"); list2.add("2"); list2.add("3"); list2.add("4"); list2.add("5"); list2.add("6"); newFor(list2); System.out.println(list1); } }
这段程序会报Exception in thread "main" java.util.ConcurrentModificationException,在newFor(list2);这一行报。这是为什么呢?
程序中的foreach语句
for (String str : list) {
if (str.equals("2")) {
list.remove(str);
}
}就相当于下面的迭代器
for (Iterator<String> it = list.iterator(); it.hasNext();) {
String str = it.next();
if (str.equals("2")) {
list.remove(str);
}
}List,Set,Map迭代的时候是不允许自身的长度改变的,所以在迭代的内部,不允许使用List,Set,Map的add方法和remove方法。
有一个笨方法可以避免这一点
public static void newFor(List<String> list) { List<String> removeList = new ArrayList<String>(); for (String str : list) { if (str.equals("2")) { removeList.add(str); } } list.removeAll(removeList); }
这样也确实可以解决问题了,但是方法实在太笨重,其实可以有更简单的更高效的方法,就是用Iterator.remove方法,如下:public static void newFor(List<String> list) { for (Iterator<String> it = list.iterator(); it.hasNext();) { String str = it.next(); if (str.equals("2")) { it.remove(); } } }