2013-08-14 15 views
6
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.ListIterator; 

public class MyList { 
    public static void main(String[] args) { 
     ArrayList<String> al = new ArrayList<String>(); 

     al.add("S1"); 
     al.add("S2"); 
     al.add("S3"); 
     al.add("S4"); 

     Iterator<String> lir = al.iterator(); 

     while (lir.hasNext()) { 
      System.out.println(lir.next()); 
     } 

     al.add(2, "inserted"); 

     while (lir.hasNext()) { 
      System.out.println(lir.next()); 
     } 
    } 
} 

Konkretny kawałek kodu zgłasza błąd:java.util.ConcurrentModificationException podczas wkładania w ArrayList

Exception in thread "main" java.util.ConcurrentModificationException 
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source) 
    at java.util.ArrayList$Itr.next(Unknown Source) 
    at collections.MyList.main(MyList.java:32) 
+0

Założę mogę znaleźć więcej niż 10 duplikatów w SO. –

Odpowiedz

3

Jesteś modyfikując Collection, a następnie próbuje użyć tego samego iterator.

  1. Pobierz iterator kolekcję ponownie

    al.add(2, "inserted"); 
    Iterator<String> lirNew = al.iterator(); 
    while (lirNew.hasNext()) { 
    System.out.println(lirNew.next()); 
    } 
    
  2. lub Użyj ListIterator

    ArrayList<String> al = new ArrayList<String>(); 
    
    al.add("S1"); 
    al.add("S2"); 
    al.add("S3"); 
    al.add("S4"); 
    
    ListIterator<String> lir = al.listIterator(); 
    
    while (lir.hasNext()) { 
        System.out.println(lir.next()); 
    
    } 
    
    lir.add("insert"); 
    
    while (lir.hasNext()) { 
        System.out.println(lir.next()); 
    
    } 
    
6

Zdarza się, ze względu na listę tablica jest modyfikowana po utworzeniu Iterator.

The iterators returned by this ArrayList's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Documentation

Iterator<String> lir = al.iterator(); // Iterator created 

while (lir.hasNext()) 
    System.out.println(lir.next()); 
al.add(2, "inserted"); // List is modified here 
while (lir.hasNext()) 
    System.out.println(lir.next());// Again it try to access list 

Co należy zrobić tutaj utworzyć nowy obiekt iteratora po modyfikacji.

... 
al.add(2, "inserted"); 
lir = al.iterator(); 
while (lir.hasNext()) 
    System.out.println(lir.next()); 
0

Dodajecie obiekt do listy po instancji iteratora. Spowoduje to zmianę wartości modCount w klasie wewnętrznej AbstractList $ Itr.class. Metoda next() iteratora wywoła metodę checkForComodification(), która zgłasza wyjątek ConcurrentModificationException. A to jest tak zwane fail-szybko.

//add in abstractList 
public void add(int index, E element) { 
    if (index<0 || index>size) 
     throw new IndexOutOfBoundsException(); 
    checkForComodification(); 
    l.add(index+offset, element); 
    expectedModCount = l.modCount; 
    size++; 
    modCount++; //modCount changed 
} 

W AbstractList $ ITR

int expectedModCount; 

public E next() { 
     checkForComodification(); // cause ConcurrentModificationException 
    try { 
    E next = get(cursor); 
    lastRet = cursor++; 
    return next; 
    } catch (IndexOutOfBoundsException e) { 
    checkForComodification(); 
    throw new NoSuchElementException(); 
    } 
} 

private void checkForComodification() { 
    if (l.modCount != expectedModCount) //modCount not equals to itr.expectedModCount 
     throw new ConcurrentModificationException(); 
} 

przerobić ten kod po dodatku:

al.add(2, "inserted"); 
lir = al.iterator(); 
+0

yah, ale dlaczego tak się dzieje, gdy ograniczałem zakres iteratora do pętli while? – user2681668

+0

Nie jest to spowodowane zasięgiem, ale wywołaniem funkcji add(). Lepiej przeczytaj kod źródłowy jdk. – criszhao

Powiązane problemy