2012-11-25 118 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封閉實例,它保持的軌道場修改次數。