先来看一个程序
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();
}
}
}