2016-10-02 55 views
-5

支持數據結構是一個HashMap,它基本上是一個Entry數組。由於支持結構是一個數組,迭代順序如何隨時間變化?Java *中的HashSet如何在迭代時不保證順序?

+7

你的基本假設(它只是一個數組而不是別的)是不正確的。閱讀哈希表數據結構上的Wikipedia文章。 –

+0

HashMap只是一個數組。請參閱http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/HashMap.java#HashMap.0table – user2698

+3

@ user2698 - 是的......但是你看看其餘的代碼?方法...例如?它不僅僅是一個數組**而且沒有別的**。 –

回答

2

散列集的迭代次序是任意的,但它是確定性的。

訂單不隨時間變化,除非集合在迭代之間發生變化。給定相同的項目集合和特定的插入順序,迭代順序將保持不變。

如果插入或刪除項目,迭代順序將發生變化。底層數據結構(一個列表節點數組)保持不變,但由於將項目放置到哈希桶中是由項目的哈希代碼確定的,因此當您迭代哈希時,無法確定特定項目最終會到達哪裏組。

文檔確實say迭代的順序不能保證:

[HashSet]不保證,以該集合的迭代順序;特別是,它不能保證訂單會隨着時間的推移保持不變。

的「一段時間」的部分是相當模糊的,原因有二:如果「隨着時間的推移」指的是你的程序的運行時間,或升級到Java類庫之間的時間目前尚不清楚,和在允許改變迭代次序的時間內是否允許修改也是不清楚的。然而,知道散列集的組織和實現方式,迭代次序在缺少更新時仍然保持確定性是非常接近的確定性。但這並不意味着您可以依靠訂單,因爲它隨時都可能發生變化。

+1

我不認爲這是真的。從javadocs:「它不能保證集合的迭代順序;特別是,它不能保證順序會隨着時間的推移保持不變。」從這句話我明白,即使你不添加/刪除任何元素,迭代順序仍然可以改變。 – user2698

+3

@ user2698 - 那麼,對於'HashSet'的不同實現,它們可以改變!關鍵在於javadoc是一個契約,即使它的代碼被完全重寫,HashSet的過去,現在和未來版本也會滿足這個契約。合同規定「不要依賴在某些情況下我們不能告訴你的訂單不變......」。 –

+3

哦,是的...和序列化/反序列化可能會改變迭代順序,就像使用'new HashSet(set)'複製一樣。 –