ArrayList刪除指定元素
阿新 • • 發佈:2018-12-26
問題一:移除元素有漏掉
操作:
@SuppressWarnings({ "rawtypes", "unchecked" }) private static void listRemove() { final ArrayList list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); System.out.println("list長度.size():" + list.size()); for (int i = 0; i < list.size(); i++) { list.remove(i); System.out.println("移除第" + i + "個元素之後list內元素有:" + list.toString() + "list長度.size()為:" + list.size()); } System.out.println("移除結束list內元素有:" + list.toString()); }
結果:
排查:
list.remove()方法操作為:
public E remove(int index) { RangeCheck(index); modCount++; E oldValue = (E) elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // Let gc do its work return oldValue; }
方法System.arraycopy(elementData, index+1, elementData, index, numMoved);將移除位置後每一位向前複製一位第一次移動得到的elementData=[2,3,4,4,null.null,...]
方法 elementData[--size] = null; 將最後一位指向null方便GC回收
第一個元素移除結束後得到的list為[2,3,4],list元素位發生變化,第二次移除index=1移除元素為3得到的list為[2,4],size=2此時i=1,下次移除i=2不符合條件,操作結束。
解決方式:
指定刪除的位置或使用迭代器:
@SuppressWarnings({ "rawtypes", "unchecked" })
private static void listRemoveItr() {
final ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Iterator iterator = list.iterator();
System.out.println("刪除前集合的長度為:" + list.size() + ":" + list);
for (; iterator.hasNext() && !"".equals(iterator.next());) {
iterator.remove();
}
System.out.println("刪除後集合的長度為:" + list.size() + ":" + list);
}
問題二:ConcurrentModificationException異常
以上方式寫成如下,會報java.util.ConcurrentModificationException異常:
@SuppressWarnings({ "rawtypes", "unchecked" })
private static void listRemoveItr() {
final ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Iterator iterator = list.iterator();
System.out.println("刪除前集合的長度為:" + list.size() + ":" + list);
for (; iterator.hasNext() && !"".equals(iterator.next());) {
// iterator.remove();
list.remove(Integer.valueOf(3));
}
System.out.println("刪除後集合的長度為:" + list.size() + ":" + list);
}
原因及修改方式:
https://www.cnblogs.com/andy-zhou/p/5339683.html
參考:https://www.cnblogs.com/andy-zhou/p/5339683.html
https://blog.csdn.net/liusong0605/article/details/48105103