首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java框架集合Iterator框架集合的不同结果

Java框架集合Iterator框架集合的不同结果
EN

Stack Overflow用户
提问于 2019-04-06 13:14:38
回答 1查看 115关注 0票数 1

我对Iterator在主要类上的不同行为提出了一些问题(不仅仅是针对List类)。

  1. 列表

如果我为-每一个写-我将有一个例外:

代码语言:javascript
复制
Collection<String> cc= new ArrayList<>(3);
        cc.add("Cio");
        cc.add("Mio");
        cc.add("Tio");
for (String s:cc) {
    System.out.println(s);
    cc.remove(s);            //Exception
}

如果我使用Iterator,我也不会有例外:

代码语言:javascript
复制
for (Iterator<String> it =cc.iterator(); it.hasNext();) {
    String s =it.next();
    if (s.startsWith("C"))
        it.remove();
}
  1. ArrayDeque

这对于ArrayDeque来说是不同的,事实上,如果我使用-每一个,我也不会有一个例外:

代码语言:javascript
复制
ArrayDeque<String> greetings = new ArrayDeque<String>();
        greetings.push("hello");
        greetings.push("hi");
        greetings.push("ola");
        greetings.pop(); 
        greetings.peek();
        while (greetings.peek() != null)
        System.out.print(greetings.pop());

但是,如果我使用迭代器,我将有一个例外:

代码语言:javascript
复制
Iterator<String> it = greetings.iterator();
        while(it.hasNext()) {
            System.out.println(greetings.pop()); //Exception
        }

为什么?迭代器是否为其他JFC集合抛出异常,特别是: HashSet、TreeSet、LinkedList?

非常感谢!

一个。

EN

回答 1

Stack Overflow用户

发布于 2019-04-06 14:51:13

ArrayList

列表维护一个modCount字段,该字段每次对列表进行结构修改时都会递增。

结构修改是那些改变列表大小的修改,或者以其他方式干扰它,以致正在进行的迭代可能产生不正确的结果。

更远..。

如果该字段的值意外更改,则迭代器(或列表迭代器)将抛出一个ConcurrentModificationException,以响应下一个操作、删除、前一个操作、设置或添加操作。这提供了快速失败的行为,而不是在此字段的iteration.Use中由子类进行并发修改时的非确定性行为是可选的。 如果一个子类希望提供快速失败的迭代器(和列表迭代器),那么它只需要在其add(int,E)和remove(int)方法中增加这个字段(以及它覆盖导致对列表进行结构修改的任何其他方法)。

列表迭代代码的两个部分:

1.

代码语言:javascript
复制
for (String s:str1) {
    System.out.println(s);
    str1.remove(s);  
}

2.

代码语言:javascript
复制
Iterator<String> i1 = str.iterator();
while(i1.hasNext()) {
    i1.next();
    i1.remove();
}

-看上去可能是一样的,但内部却有点不同。

值得一提的是,列表的迭代器保持一个expectedModCount。在迭代时修改列表时,这应该与modCount同步。

在第一种情况下,String s:str1获取迭代器,检查hasNext()并调用next(),就像在第二种情况下一样。不同之处在于remove()方法调用。str1.remove(s);调用ArrayList的remove方法。这会增加modCount,但不会增加expectedModCount。因此,在第二次迭代中,当调用next()时,它会抛出ConcurrentModificationException。另一方面,在第二种情况下,i1.remove();在ArrayList中调用Iterator实现中的remove方法。这增加了modCountexpectedModCount以及--宾果。

注意:在第二个场景中缺少i1.next();将导致IllegalStateExcepton。这是因为列表中下一个元素的游标没有更新。

TakeAway:在迭代列表时不调用list.remove(element)方法。此方法用于在不进行迭代时调用。

ArrayDeque

如果您像这样迭代ArrayDeque:

代码语言:javascript
复制
Iterator<String> i1 = str.iterator();
while(i1.hasNext()) {
    i1.next();
    i1.remove();
}

--它的工作方式与ArrayList完全相同.

当调用pop()或ArrayDeque类的push()方法时,实际上并不迭代队列,只需修改队列的头或尾。这就像在不进行迭代时调用ArrayList类的remove()方法一样(不是ArrayList的Iterator的remove() )。这不符合结构调整的条件。所以它不会抛出异常。

请参阅文章。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55549414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档