我得到这个定义:顾名思义,一旦迭代开始,快速失败迭代器就会失败,因为它们意识到集合的结构已经改变。
自从迭代开始以来是什么意思? 这是在迭代器之后的意思吗?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();**
首先,它们是故障快速的,而不是故障安全的。
合约是某些类型集合的结构修改(即插入/删除)使集合中的现有迭代器无效。快速失败迭代器尝试检测它们不应该有效并抛出ConcurrentModificationException
。这是作为对您(程序员)的服务来完成的,以帮助更快地发现此类错误。
在您的示例中:
Iterator it = set.iterator();
it.next();
set.add("unique-entry"); // invalidates the iterator
it.next();
如果幸运的话,第二个it.next()
将检测到无效用法并引发异常。请注意,这是在尽力而为的基础上完成的,不能保证。
这是否意味着在迭代器之后它=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
的封闭实例中的一个字段,用于跟踪修改的数量。
迭代器快速失败意味着以下代码段预计会失败:
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
因为会发生以下一系列事件:创建迭代器,然后更改其基础集合,然后访问迭代器。
是的,如果您打算迭代它,请不要在使用 .iterator() 后更改集合,如果您想删除最新元素,您可以使用 .remove()
在快速失败迭代器开始工作之前,它会获取集合计数,并且在任何迭代后,它会检查计数是否更改,如果计数更改,JVM将抛出ConcurrentModificationException。Fail fast 迭代器是 java.util 包(例如 ArrayList、LinkedList 等)内集合的任何迭代器,而 Fail Safe 迭代器是 java.concurrent 包(例如 CopyOnWriteArrayList、CopyOnWriteSet 等)内的迭代器。快速失败迭代器将在并发修改的情况下抛出异常,但故障安全迭代器基本上是使用集合的副本,在并发修改的情况下不会抛出异常。