【问题标题】:UnsupportedOperationException while iterating over CopyOnWriteArrayList迭代 CopyOnWriteArrayList 时出现 UnsupportedOperationException
【发布时间】:2019-02-27 06:37:18
【问题描述】:

我在一本书中看到以下陈述:

在基于写时复制的IteratorListIterator 上调用的任何变异方法(例如添加、设置或删除)都会抛出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 时没有收到异常?

【问题讨论】:

  • 你永远不会在 Iterator 或 ListIterator 上调用任何方法。
  • 您在CopyOnWriteArrayList 上调用remove,而不是在您引用的文本中提到的迭代器上。它是UnsupportedOperationException,而不是UpsupportedOperationException

标签: java collections concurrency iterator copyonwritearraylist


【解决方案1】:

您正在调用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
}

【讨论】:

    【解决方案2】:

    Mureinik 的回答看起来不错。但是,如果你深入研究这个 -

    如果使用ArrayList

    • 使用for循环并列出remove(current_index)方法,效果很好。

    并且使用iterator 方法-

    • 使用迭代器 remove() 方法而不是列表 remove(),它工作正常
    • 如果使用列表remove()方法,则抛出ConcurrentModificationException

    如果在多线程环境中 -

    使用CopyOnWriteArrayList

    • 使用列表remove(current_element) 可以正常工作
    • 使用IteratorListIterator 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);       
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多