UnsupportedOperationException при итерации по CopyOnWriteArrayList
Я наткнулся на следующее утверждение в книге:
Любые мутирующие методы, вызываемые на основе копирования при записи.
Iterator
или жеListIterator
(например, добавить, установить или удалить)UnsupportedOperationException
,
Но когда я запускаю следующий код, он работает просто отлично и не выдает UnsupportedOperationException
,
List<Integer> list = new CopyOnWriteArrayList<>(Arrays.asList(4, 3, 52));
System.out.println("Before " + list);
for (Integer item : list) {
System.out.println(item + " ");
list.remove(item);
}
System.out.println("After " + list);
Код выше дает следующий результат:
Before [4, 3, 52]
4
3
52
After []
Почему я не получаю исключение, пока я изменяю данное list
с использованием remove
метод?
2 ответа
Ты звонишь remove
в самом списке, что нормально. Документация гласит, что вызов remove
на итераторе списка будет бросать UpsupportedOperationException
, Например:
Iterator<Integer> iter = list.iterator();
while (iter.hasNext()) {
Integer item = iter.next();
System.out.println(item + " ");
iter.remove(); // Will throw an UpsupportedOperationException
}
Хорошо смотрится ответ Мурейника. Однако если вы погрузитесь в это глубоко -
При использовании
ArrayList
- Использовать
for
цикл и списокremove(current_index)
метод, он работает нормально.
И с
iterator
подход -
- Используйте метод итератора вместо списка, он отлично работает
- Броски
ConcurrentModificationException
если использовать метод списка
Если в многопоточной среде -
Использовать
CopyOnWriteArrayList
- Со списком
remove(current_element)
он отлично работает - С
Iterator
или жеListIterator
remove()
метод, он бросаетUnsupportedOperationException
Взгляните на пример ниже -
import java.util.*;
import java.util.concurrent.*;
public class AvoidCMEExample {
public static void main(String args[]) {
List<String> listOfBooks = new ArrayList<>();
listOfBooks.add("Programming Pearls");
listOfBooks.add("Clean Code");
listOfBooks.add("Effective Java");
listOfBooks.add("Code Complete");
System.out.println("List before : " + listOfBooks);
/*for(int i=0; i<listOfBooks.size(); i++){
String book = listOfBooks.get(i);
if(book.contains("Programming")){
System.out.println("Removing " + book);
listOfBooks.remove(i); // works fine
}
}*/
Iterator<String> itr = listOfBooks.iterator();
while(itr.hasNext()){
String book = itr.next();
if(book.contains("Programming")){
System.out.println("Removing " + book);
//listOfBooks.remove(book); // will throw CME
itr.remove(); // using iterator remove(), it works fine
}
}
System.out.println("List after : " + listOfBooks);
List<String> list = new CopyOnWriteArrayList<>();
list.add("B"); list.add("W"); list.add("Q"); list.add("S");
System.out.println("\n\nList before : " + list);
Iterator<String> itr1 = list.iterator();
while(itr1.hasNext()){
String book = itr1.next();
if(book.contains("Q")){
System.out.println("Removing " + book);
list.remove(book); // works fine on list object remove()
itr1.remove(); // throws UnsupportedOperationException on iterator, ListIterator obj
}
}
System.out.println("List after : " + list);
}
}