Java 迭代器、列表迭代器和CopyOnWriteArrayList之间的差异

Java 迭代器、列表迭代器和CopyOnWriteArrayList之间的差异,java,collections,java.util.concurrent,listiterator,copyonwritearraylist,Java,Collections,Java.util.concurrent,Listiterator,Copyonwritearraylist,考虑一个ArrayList,其中对于迭代器和列表迭代器操作,当列表被迭代时,每当集合对象发生更改时,它抛出ConcurrentModificationException,如下所示: package JavaImpPrograms; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Wdfds { publi

考虑一个ArrayList,其中对于迭代器和列表迭代器操作,当列表被迭代时,每当集合对象发生更改时,它抛出ConcurrentModificationException,如下所示:

    package JavaImpPrograms;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    public class Wdfds {

        public static void main(String[] args) {

            List<Integer> list=new ArrayList<>();

            list.add(1);
            list.add(2);
            list.add(3);
            list.add(4);

            Iterator it=list.iterator();

            while(it.hasNext()){

            Integer i= (Integer) it.next();

            if(i%2==0)
            list.remove(0);             
            }

            System.out.println(list); } }
当涉及copyOnWriteArrayList时,如果迭代器对象使用下面的普通迭代器的移除操作进行更新(或listIterator被更新(添加/移除),它将抛出UnsupportedOperationException:

    package JavaImpPrograms;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.CopyOnWriteArrayList;

    public class Wdfds {

        public static void main(String[] args) {

            List<Integer> list=new CopyOnWriteArrayList<>();

            list.add(1);
            list.add(2);
            list.add(3);
            list.add(4);

            Iterator it=list.iterator();

            while(it.hasNext()){

            Integer i= (Integer) it.next();

            if(i%2==0)
            it.remove();            
            }

            System.out.println(list); } }
打包javaimp程序;
导入java.util.Iterator;
导入java.util.List;
导入java.util.concurrent.CopyOnWriteArrayList;
公共类WDFD{
公共静态void main(字符串[]args){
List List=新CopyOnWriteArrayList();
增加第(1)款;
增加(2);
增加(3);
增加(4);
Iterator it=list.Iterator();
while(it.hasNext()){
整数i=(整数)it.next();
如果(i%2==0)
it.remove();
}
System.out.println(列表);}

打包javaimp程序;
导入java.util.List;
导入java.util.ListIterator;
导入java.util.concurrent.CopyOnWriteArrayList;
公共类WDFD{
公共静态void main(字符串[]args){
List List=新CopyOnWriteArrayList();
增加第(1)款;
增加(2);
增加(3);
增加(4);
ListIterator it=list.ListIterator();
while(it.hasNext()){
整数i=(整数)it.next();
如果(i%2==0)
加入(9);
}
System.out.println(列表);}
对于上述结果,我有几个问题:

1) 对于ArrayList,如果迭代器能够在迭代期间使用迭代器对象修改列表,为什么要将copyOnWriteArrayList用于

1) 为什么copyOnWriteArrayList迭代器更新在遇到迭代器对象更改时抛出UnsupportedOperationException,而在集合对象发生更改时却没有异常

3) 看起来上面两个场景是相反的。请告诉我这些场景是什么时候使用的,在哪些场景中使用的


这完全令人困惑

您的问题都由以下人员回答:

ArrayList
的一种线程安全变体,其中所有的变异操作(
add
set
等)都是通过创建基础数组的新副本来实现的

查看的文档显示

当构造迭代器时,返回的迭代器提供列表状态的快照。遍历迭代器时不需要同步。迭代器不支持remove方法

重要的一点是,
迭代器
只提供列表的快照

要求有以下行为:

从基础集合中移除此迭代器返回的最后一个元素(可选操作)


由于
CopyOnWriteArrayList
iterator()
只是列表的快照,因此
iterator
看到的某些元素可能已经从列表中删除,因此(再次)删除它可能会引起麻烦(例如,当同一对象多次出现在列表中时)。唯一合乎逻辑的结果是通过抛出一个
UnsupportedOperationException

来拒绝该操作。迭代器有两种类型:故障安全迭代器和故障快速迭代器。迭代器是fail fast,这意味着当您遍历集合并试图通过添加新元素修改集合结构时,会抛出ConcurrentModificationException

为了克服这个问题,我们使用了故障安全的CopyOnWriteArrayList,我们可以在遍历列表时添加元素

很明显,当我们 调用迭代器next()函数。如果您想知道迭代器 检查修改,其实现在 定义了int变量modCount的AbstractList类。模态数 提供更改列表大小的次数。模态数 值用于每次next()调用,以检查 函数checkForComodition()


创建CopyOnWriteArrayList是为了允许 即使在基础列表 修改

由于复制机制,在 不允许返回迭代器–结果为 不支持操作异常


请正确设置代码格式。但为什么CopyOnWriteArrayList会对迭代器对象更新引发异常?创建CopyOnWriteArrayList是为了允许在修改基础列表的情况下对元素进行安全迭代。由于复制机制,不允许对返回的迭代器执行remove()操作–导致UnsupportedOperationException:
    package JavaImpPrograms;
    import java.util.Iterator;
    import java.util.List;
    import java.util.concurrent.CopyOnWriteArrayList;

    public class Wdfds {

        public static void main(String[] args) {

            List<Integer> list=new CopyOnWriteArrayList<>();

            list.add(1);
            list.add(2);
            list.add(3);
            list.add(4);

            Iterator it=list.iterator();

            while(it.hasNext()){

            Integer i= (Integer) it.next();

            if(i%2==0)
            it.remove();            
            }

            System.out.println(list); } }
package JavaImpPrograms;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;

public class Wdfds {

    public static void main(String[] args) {

        List<Integer> list=new CopyOnWriteArrayList<>();

        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        ListIterator it=list.listIterator();

        while(it.hasNext()){

        Integer i= (Integer) it.next();

        if(i%2==0)
        it.add(9);          
        }

        System.out.println(list); } }