ArrayList remove注意事項


 

例子1:

List<Integer>list=new ArrayList<>();
 list.add(1);
 list.add(2);
 list.add(2);
 list.add(3);
 list.add(4);
 list.add(5);
 for(int i=0;i<list.size();i++){
  if(list.get(i)%2==0){
   list.remove(list.get(i));
  }
}
System.out.println(list);

 

輸出結果:

[1, 2, 3, 5]

分析:
第三個元素沒有remove 掉,跟蹤:
第一次循環
i=0 size=5 當前元素=1 不移除元素
i=1 size=5 當前元素=2 移除元素
i=2 size=4 當前元素=3 不移除元素


在remove 的過程中 size 是移動的,所以 第三個元素給漏掉了

 

例子2:

List<Integer>list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(2);
list.add(3);
list.add(4);
list.add(5);

System.out.println(list);*/

for (Integer a:list){
 if(a == 2){
  list.remove(a);
 }
}

  

拋出異常:

java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at com.student.eureka1.StudentEureka1ApplicationTests.contextLoads(StudentEureka1ApplicationTests.java:31)

  

原因:
拋出異常代碼

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];
}

final void checkForComodification() {
// 是因為 modCount != expectedModCount 不相等
  if (modCount != expectedModCount)
  throw new ConcurrentModificationException();
}

  

在使用for(Object obj:objList) 這種增強for 循環的時候,每次遍歷會進行hasNext 判斷,它會創建 List的遍歷器Iterator ,在創建的時候它會將 modCount 賦值給 expectedModCount 。並且調用Iterator 的 next 方法。

在沒有調用 list.remove(a); 方法前,expectedModCount 和 modCount是相等的。

當調用后    注意 list.remove(a); 調用的不是Iterator 的remove 方法,而是 ArrayList的remove 方法, ArrayList的remove 方法 只會更新 modCount 值,不會更新expectedModCount 值,所以不相等報錯

(簡單點就是說:你用了Iterator 遍歷 但是在里面不是用Iterator  的 remove 方法導致)

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];
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM