Odpowiedź 4 jest poprawna technicznie, ale nie dlatego, że zamiast pętli while()
używana jest pętla for(;;)
lub "dla każdego". Jest to po prostu kwestia zadeklarowanego zakresu Iteratora w ramach klasy, a nie metody. Najpierw przyjrzyjmy się zachowaniu dwóch metod: po prostu zapytujemy wewnętrzny kursor (indeks); next()
faktycznie przesuwa kursor, dlatego jest to "modyfikacja", która może podnieść wyjątek. Jeśli spróbujesz użyć zadeklarowanej iteracji i przypisanej poza metodą, w której jest używany next()
, kod wygeneruje wyjątek na pierwszym next()
, niezależnie od tego, czy jest to for(;;)
czy while()
.
W odpowiedziach 4 i 8 iterator jest zadeklarowany i spożytkowany lokalnie w ramach metody. Tak się składa, że konstrukt for(;;)
pozwala na deklarację po raz pierwszy i przypisanie iteratora przed wykonaniem pętli (co powoduje, że iterator ma zasięg for(;;)
i niejawnie w metodzie, czyniąc go "bezpiecznym"). Zgadzam się, że idiom for(;;)
jest czystszy pod względem składniowym i płotowym na najniższym poziomie wykonania, całkowicie w ramach pętli for(;;)
.
Odpowiedź 8 jest poprawna, ponieważ Iterator jest przypisany i używany lokalnie w metodzie.
Ale tylko dla dobra dyskusji, poniższa metoda z użyciem while()
oświadczenie jest składniowo poprawne, „bezpieczny” i bez modyfikacji z punktu widzenia zakresu i odniesienia:
gdzieś w definicji klasy .. .
ArrayList<String> messageList;
gdzieś w konstruktorze klasy
messageList = new ArrayList<String>();
dodać metodę ...
public printMessages ()
{
Iterator<String> messageIterator = messageList.iterator();
while (messageIterator.hasNext())
{
System.out.println(messageIterator.next());
}
System.out.flush();
}
Duplikat http://stackoverflow.com/questions/223918/iterating-through-a-collection-avoiding-concurrentmodificationexception-when-re – Raedwald