【问题标题】:Why doesnt hasnext,hasprevious etc methods of Iterator or listIterator check for ConcurrentModificationException为什么没有Iterator或listIterator的ext,hasprevious等方法检查ConcurrentModificationException
【发布时间】:2014-01-30 07:24:20
【问题描述】:

我知道failfast迭代器会尽最大努力检查ConcurrentModificationException。为什么hasext或hasPrevious等方法不检查ConcurrentModificationException并抛出它???

以下代码运行良好的确切原因是,尽管已对 CME 进行了结构修改,但不会检查这些方法

public static void main(String[] args) {
        // TODO Auto-generated method stub


        List<String> lilong = new ArrayList<String>();
        lilong.add("Queen");
        for(Iterator<String> iter =lilong.iterator();iter.hasNext();)
        {
            System.out.println(iter.next());
            lilong.add("King");
            lilong.remove(0);
            lilong.add("Star");
            lilong.remove(0);
            lilong.add("Sun");
            lilong.remove(0);
            lilong.add("Polar Bear");
            lilong.clear();

            lilong.add("There you go");

        }
        System.out.println("size="+ lilong.size()+"##element##"+lilong.iterator().next());
    }

【问题讨论】:

  • 我在这里没有看到任何迭代器。
  • 迭代器隐藏在 for-each 语句中。
  • @Kayaman 我的意思是iterator()
  • 对于每个循环都被编译器内部推断为迭代器
  • 是的,for(String s : lilong) 使用 lilong.iterator() 转换为代码。

标签: java collections


【解决方案1】:

hasNext 用于 ArrayList 的迭代器检查修改,它只查看大小。

如果您在列表中再添加一个元素,您将进入第二次迭代,然后next 将按预期失败。

至于为什么以这种方式实施... +1 对您的问题。

【讨论】:

  • 是的,但它可以使用 next() 和 remove() 方法使用的此方法进行检查:- final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException();这是从 remove() 和 next() 方法调用的,但不是从 hasext() 方法调用的
  • “是的,但它可以检查”。真的。但事实并非如此。
【解决方案2】:

编辑:删除了一堆废话

所以问题是:为什么hasNext() 不像其他迭代器方法那样检查并发修改。

如果我敢打赌,hasNext() 没有太多用处,除非紧随其后的是 next()。所以不是在两个地方检查,而是在next()

【讨论】:

  • 是的..这点。如果它检查了 hasNext() 方法的并发修改异常,它肯定也适用于这种情况。迭代器仅检查 CME 的 next() 和 remove( )
  • @AbhinavKumar 我实际上不确定您的代码试图显示什么。即使 hasNext() 检查了 CME,示例代码仍会像现在一样运行。
  • 我需要替换我的迭代器构造代码,这样我才会更清楚
  • 是的,但 hasext() 绕过了这个检查。所以我想知道 CME 怎么不会被抓到
  • ArrayList 的 javadoc 说“仅仅设置元素的值不是结构修改。”,所以 list.set(0, "foo") 不会导致 CME。哦等等,那是谈论外部修改的部分,所以它仍然可能导致 CME。没有,刚试过。 set(index, obj) 方法不会导致 CME。
猜你喜欢
  • 2020-04-29
  • 2012-06-27
  • 2014-05-14
  • 2016-05-26
  • 2021-07-01
  • 2011-01-06
  • 2018-01-05
  • 2011-02-24
  • 2020-10-21
相关资源
最近更新 更多