簡體   English   中英

為什么HashMap快速失敗只是因為它提供了迭代其鍵的方法?

[英]Why is HashMap fail-fast just because it provides a means to iterate over its keys?

這就是我所知道的:


  • 如果我在迭代它時嘗試修改給定元素,而不使用迭代器的方法(如iterator.remove() ),則失敗快速迭代器將拋出ConcurrentModificationException
  • 不能保證快速失敗的迭代器總是會拋出一個CME。
  • 故障安全迭代器不會拋出CME。

我正在讀一本書,其中我遇到了以下句子:

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()

查看包含該確切句子的網頁,我認為上下文是HashMapHashTable的比較。 如果你看看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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM