[英]Why is HashMap fail-fast just because it provides a means to iterate over its keys?
這就是我所知道的:
iterator.remove()
),則失敗快速迭代器將拋出ConcurrentModificationException
我正在讀一本書,其中我遇到了以下句子:
HashMap提供了一組鍵,Java應用程序可以迭代它們。 因此,HashMap是快速失敗的。
我不明白的部分是“所以......”。 如果有人告訴我HashMap提供了一組密鑰,我仍然不知道它是快速失敗還是故障安全(僅基於此)。
那么為什么提供自己的密鑰組會使HashMap快速失敗呢?
這兩件事之間的聯系是什么 ?
它實際上是第一個提供HashMap快速失敗信息的句子:
HashMap提供了一組鍵,Java應用程序可以迭代它們。
失敗安全迭代器迭代原始集合的私有副本,而不是集合本身。 因此,對原始集合的任何更改都不會被迭代器注意到,因此它永遠不會拋出CME 。
由於HashMap
提供了上面引用中的一組鍵(而不是副本),因此它是快速失敗的。
作者只是沒有完成這個想法。
來自HashMap的javadocs( https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#keySet() ):
“返回此映射中包含的鍵的Set視圖。該集由映射支持,因此對映射的更改將反映在集合中,反之亦然。如果在集合上的迭代進行時修改了映射進度(通過迭代器自己的刪除操作除外),迭代的結果是未定義的。該集支持元素刪除,它通過Iterator.remove,Set.remove,removeAll,retainAll和clear從地圖中刪除相應的映射。它不支持add或addAll操作。“
沒有表達的想法是使用keySet提供的Set迭代哈希映射(好吧,讓我們把它當作迭代地圖......)。 由於該集合是快速失敗的(根據上面的文檔),因此映射也是快速失敗的。
請記住,其他方法允許迭代地圖(但幸運的是,就我所見,它們也是快速失敗的)。 檢查https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#entrySet()
查看包含該確切句子的網頁,我認為上下文是HashMap
與HashTable
的比較。 如果你看看Javadoc為HashTable
所說的內容,可以更清楚:
所有這個類的“集合視圖方法”返回的集合的迭代器方法返回的迭代器都是快速失敗的 :如果在創建迭代器之后的任何時候對Hashtable進行結構修改,除非通過迭代器自己的刪除方法,迭代器將拋出ConcurrentModificationException。 因此,在並發修改的情況下,迭代器快速而干凈地失敗,而不是在未來的未確定時間冒着任意的,非確定性行為的風險。 Hashtable的鍵和元素方法返回的枚舉不是快速失敗的。
因此,有了這個背景,我們可以看出HashMap與HashTable比較的作者試圖說HashMap是快速失敗的,因為它有一個keySet()
方法,它返回如上所述的快速失敗的迭代器的Javadoc。 但是,這會提供不完整的信息,因為它可以暗示,與HashMap不同,HashTable不是快速失敗的。 事實上,HashTable實現了Map
,因此也有keySet()
方法,因此它也像HashMap一樣具有快速失敗的迭代器。 該句子的另一個問題是它具有誤導性:HashMap不是快速失敗的,而是它返回的迭代器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.