for(int i=0;i<list.size();i++){ if(list.get(i).equals("del")) list.remove(i); }
这种方式的问题在于:删除某个元素后,list的大小发生了变化,而你的索引也在变化,所以会导致你在遍历的时候漏掉某些元素。
比如当你删除第1个元素后,后面的元素都往前移动了一位;继续根据索引访问第2个元素时,实际访问的是原来的第3个元素。
因此,这种方式可以用在删除特定的一个元素时使用,但不适合循环删除多个元素时使用。
for(String x:list){ if(x.equals("del")) list.remove(x); }
这种方式的问题在于,删除元素后继续循环会报错误信息ConcurrentModificationException,因为元素在使用的时候发生了并发的修改,导致异常抛出。
但若删除完毕马上使用break跳出,则不会触发报错。
Iterator<String> it = list.iterator(); while(it.hasNext()){ String x = it.next(); if(x.equals("del")){ it.remove(); } }
iterator方式可以正常的循环及删除。
但如果用list的remove方法同样会报上面提到的ConcurrentModificationException错误。
(1)循环删除list中特定一个元素的,可以使用三种方式中的任意一种,但在使用中要注意上面分析的各个问题。
(2)循环删除list中多个元素的,应该使用迭代器iterator方式。
/** * Removes the element at the specified position in this list. * Shifts any subsequent elements to the left (subtracts one from their * indices). * * @param index the index of the element to be removed * @return the element that was removed from the list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E remove(int index) { rangeCheck(index); modCount++; E oldValue = elementData(index); // 要删除的元素 int numMoved = size - index - 1; //要移动的元素个数 if (numMoved > 0) // 整体左移 System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; }
public Iterator<E> iterator() { return new Itr(); } 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; Itr() {} 。。。 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(); } } 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 boolean hasNext() { return cursor != size; }