CopyOnWriteArrayList的理解与理解

    xiaoxiao2026-09-22  0

    String[] data={"a","b","c"}; ArrayList<String> array = new ArrayList<String>(); array.add("a"); array.add("b"); array.add("c"); for(String s : array){ System.out.println(s); array.remove(s); }

    输出:Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source)

    反编译 字节码:

         50: invokevirtual #31                 // Method java/util/ArrayList.iterator:()Ljava/util/Iterator;         53: astore        4         55: goto          82         58: aload         4         60: invokeinterface #35,  1           // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;         65: checkcast     #16                 // class java/lang/String         68: astore_3         69: getstatic     #41                 // Field java/lang/System.out:Ljava/io/PrintStream;         72: aload_3         73: invokevirtual #47                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V         76: aload_2         77: aload_3         78: invokevirtual #53                 // Method java/util/ArrayList.remove:(Ljava/lang/Object;)Z         81: pop         82: aload         4         84: invokeinterface #56,  1           // InterfaceMethod java/util/Iterator.hasNext:()Z

    foreach语句转化为ArrayList.iterator,在进行next()函数时抛出异常

           可用方法:

    Iterator<String> iter=array.iterator(); while(iter.hasNext()){ String s=iter.next(); iter.remove(s);//这里的remove会调整modcount 与expectcount的关系 }

    因为CopyOnWriteArrayList在做迭代之前是做了一份“快照”,所以此时的iter是不可变的,也就是说如果在此遍历中调用iter.remove();会抛出异常:java.lang.UnsupportedOperationException

    public Iterator<E> iterator() { return new COWIterator<E>(getArray(), 0); } static final class COWIterator<E> implements ListIterator<E> { /** Snapshot of the array */ private final Object[] snapshot; /** Index of element to be returned by subsequent call to next. */ private int cursor; private COWIterator(Object[] elements, int initialCursor) { cursor = initialCursor; snapshot = elements; } public boolean hasNext() { return cursor < snapshot.length; } public boolean hasPrevious() { return cursor > 0; } @SuppressWarnings("unchecked") public E next() { if (! hasNext()) throw new NoSuchElementException(); return (E) snapshot[cursor++]; } @SuppressWarnings("unchecked") public E previous() { if (! hasPrevious()) throw new NoSuchElementException(); return (E) snapshot[--cursor]; } ... } 办法一:使用直接方式,一边遍历,一边add/remove(),这里实现遍历与写的分离所以不会错误 for(String item : list){ String tem = item + "..."; list.remove(item); list.add(tem); } 验证连接:http://www.cnblogs.com/alipayhutu/archive/2012/08/11/2634073.html
    转载请注明原文地址: https://ju.6miu.com/read-1312199.html
    最新回复(0)