迭代 CopyOnWriteArrayList 时出现 UnsupportedOperationException
UnsupportedOperationException while iterating over CopyOnWriteArrayList
我在一本书中看到了以下说法:
Any mutating methods called on a copy-on-write-based Iterator
or ListIterator
(such as add, set or remove) will throw an 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 []
为什么我在使用 remove
方法修改给定的 list
时没有收到异常?
您在列表本身 上呼叫 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
}
Mureinik 的回答看起来不错。但是,如果你深入研究这个 -
如果使用 ArrayList
- 使用
for
循环和列表remove(current_index)
方法,效果很好。
并采用 iterator
方法 -
- 使用迭代器
remove()
方法代替列表 remove()
,效果很好
- 如果使用列表
remove()
方法,则抛出 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);
}
}
我在一本书中看到了以下说法:
Any mutating methods called on a copy-on-write-based
Iterator
orListIterator
(such as add, set or remove) will throw anUnsupportedOperationException
.
但是当我 运行 以下代码时,它工作正常并且不会抛出 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 []
为什么我在使用 remove
方法修改给定的 list
时没有收到异常?
您在列表本身 上呼叫 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
}
Mureinik 的回答看起来不错。但是,如果你深入研究这个 -
如果使用 ArrayList
- 使用
for
循环和列表remove(current_index)
方法,效果很好。
并采用 iterator
方法 -
- 使用迭代器
remove()
方法代替列表remove()
,效果很好 - 如果使用列表
remove()
方法,则抛出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);
}
}