2012-11-25 100 views
3

我得到了这个定义:正如名字所暗示的那样,快速迭代器失败后,只要他们意识到Collection的结构已经发生变化因为迭代已经开始快速迭代器

这是什么意思自迭代开始以来?这是否意味着Iterator it = set.iterator()这行代码?所有的

public static void customize(BufferedReader br) throws IOException{ 
    Set<String> set=new HashSet<String>(); // Actual type parameter added 
    **Iterator it=set.iterator();** 
+0

请命名您使用的语言并使用一些有意义的标签。 – cxxl

+0

正确,谈论迭代器开始时的情况。但是,根据jsr,它不能保证快速失败,所以要小心使用它。 – lwpro2

回答

9

首先,它们是故障 - 快速,不是故障 - 安全

合同是某些类型的集合的结构修改(即插入/删除)使现有迭代器无效化为集合。失败快速迭代器试图检测它们不应该是有效的并抛出一个​​。这是作为程序员的一项服务完成的,以帮助更快地发现此类错误。

在您的例子:

Iterator it = set.iterator(); 
it.next(); 
set.add("unique-entry"); // invalidates the iterator 
it.next(); 

如果你幸运的话,第二个it.next()将检测无效使用和抛出异常。请注意,这是在尽力而为的基础上完成的,并不能保证。

+0

我已经尝试了代码。没有例外抛出。这是一个安全的例子吗? – joy

+1

再一次,它是**尽力而为**。迭代器可能会或可能不会检测到无效的用法。 – NPE

+0

谢谢。这清理了我的思想,失败 - 快速没有必要抛出异常,因为没有检测到。 – joy

2

迭代器感快速失败意味着以下的代码片预计失败:

Set<String> set = new HashSet<String>(); 
Iterator<String> it = set.iterator(); 
set.add(""); 
it.next(); // the set has changed now, and the iterator will throw an exception 

因为以下一系列事件发生:该迭代器被创建,那么它的底层集合的变化,然后迭代器被访问。

+0

@Mehrdad如果在用途之间发生2^32次修改的倍数,则Java Foundation Classes的快速故障行为仅会失败。 –

+1

我认为这就是它现在正在实施的方式,但不能保证按照规范那样。所以它在未来可能会发生很大的变化。仅使用规范提供的保证而不是对实现进行假设是非常重要的......并且AFAIK他们明确表示它是尽力而为,而不是保证的基础。 – Mehrdad

+0

@Mehrdad仍然不认为任何合理的实现(除非检查完全删除)将无法检测_this_大小写。 –

0

是,不要使用.iterator()如果您打算迭代之后改变集合,你可以使用一个.remove(),如果你想删除的最新元素,虽然

2

这是否意味着在Iterator之后it = set.iterator()这行代码?

是的。如果你看一下HashSet.iterator()的代码,你会看到,它只是这个:

return map.keySet().iterator(); 

...这代表对HashMap.KeySet.iterator()。有链中的几个环节,但最终你得到HashMap.HashIterator,其中包含此构造函数:

private abstract class HashIterator<E> implements Iterator<E> { 
    int expectedModCount; // For fast-fail 

    ... 

    HashIterator() { 
     expectedModCount = modCount; 
     ... 
    } 
} 

...其中modCount是在HashMap封闭实例,它保持的轨道场修改次数。