1.使用for循环遍历集合,并进行删除。
情况一:
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i) == 3) {
arrayList.remove(i);
}
}
结果:[1, 2]
情况二:
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i) == 1) {
arrayList.remove(i);
}
}
结果:[2, 3]
情况三:
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (int i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i) == 2) {
arrayList.remove(i);
}
}
结果:[1, 3]
2.使用foreach迭代
情况一:
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (Object i : arrayList) {
if (Integer.parseInt(i.toString()) == 1) {
arrayList.remove(i);
}
}
结果: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 test.test.IteratorTest.main(IteratorTest.java:21)
情况二:
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (Object i : arrayList) {
if (Integer.parseInt(i.toString()) == 2) {
arrayList.remove(i);
}
}
结果:[1, 3]
情况三:
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
for (Object i : arrayList) {
if (Integer.parseInt(i.toString()) == 3) {
arrayList.remove(i);
}
}
结果: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 test.test.IteratorTest.main(IteratorTest.java:15)
3.使用迭代器进行迭代。
ArrayList<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
arrayList.add(3);
Iterator<Integer> iterator = arrayList.iterator();
while (iterator.hasNext()) {
Integer next = iterator.next();
if (next == 3) {
iterator.remove();
}
}
System.out.println(arrayList.toString());
结果:[1,2]
使用迭代器是正确的选择,但是为什么foreach会报错呢?
源码如下:
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
这是arraylist的一个内部类,而foreach本质上也是使用迭代器进行遍历,但是在每次迭代的时候会去校验集合中元素的个数是否有变更,如果有变更则抛出并发修改异常。
网友评论