【问题标题】:iterator hasNext returns true but next throws exception迭代器 hasNext 返回 true 但 next 抛出异常
【发布时间】:2014-10-15 10:01:24
【问题描述】:

我只是好奇单个对象上的多个迭代器将如何表现并输入以下代码。

import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

class Test{
  public static void main(String[] a) {
    Map<Integer,String> map = new HashMap<>();
    map.put(1,"One");

    Iterator<Integer> it1 = map.keySet().iterator();
    Iterator<Integer> it2 = map.keySet().iterator();

    it1.next();
    it1.remove();
    System.out.println(it2.hasNext());
    System.out.println(it2.next());

    System.out.println(map.get(1));
  }
}

地图如预期是空的但是,我认为Iterator#hasNext 会返回false,但它却返回了trueIterator#next 抛出了ConcurrentModificationException

当使用Iterator#remove 方法从Collection 中删除一个值时,其他迭代器的hasNext 方法不应该返回false,因为不会返回任何值?

【问题讨论】:

    标签: java collections iterator hashmap set


    【解决方案1】:

    hasNext 方法只检查next 属性:

    public final boolean hasNext() {
      return next != null;
    }
    

    修改next属性的唯一方法是:

    这意味着如果您有几个Iterator 实例指向同一个集合实例,只有当您调用上述两种方法之一时,迭代器才会访问底层集合并检查其状态是否发生变化。

    请注意,如果底层集合被修改,迭代器的行为是未指定,这意味着它可能会被改变,你不应该依赖它。

    【讨论】:

    • 感谢您指出改变对象状态的确切方法。为此 +1 :)
    • 我想知道下一个参考文献会是什么......?一旦在另一个迭代器上调用 remove ,它就会从底层集合中删除.. 那么next 指的是什么..?
    【解决方案2】:

    iterator.remove()javadoc 声明:

    如果在迭代过程中以任何方式而不是通过调用此方法来修改底层集合,则迭代器的行为是未指定的。

    这正是您的代码中发生的情况,底层集合正在针对多个迭代器进行修改。

    【讨论】:

      猜你喜欢
      • 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
      相关资源
      最近更新 更多