[語法] 相同的物件們放到 HashSet 取出的順序

作者: obelisk0114 (追風箏的孩子)   2019-12-26 19:43:06
之前一直認為相同的物件們放到 HashSet, 由於內部順序是 hash 決定
取出的順序會是一樣
ex:
n 個 HashSet, n 個內容相同的字串群組 (每組都有 m 個字串, 可能排列順序不同)
將這 n 個字串群組分別塞進 n 個 HashSet
取出的順序會是相同的
也就是 for (String s : 任一個 HashSet) 得到的字串順序會一樣
直到最近在 Spring Boot 寫測試
直接用 assertIterableEquals(兩個 HashSet) 有時會錯誤
將兩個 HashSet 內容印出來才發現有時候順序會不一樣
更神奇的是相同一段程式碼, 執行 2 次還會有不一樣的結果
所以 HashSet 內部順序不只和 hash 有關嗎 ?
環境 :
jdk 1.8.221
Spring Boot 2.2.1.RELEASE
org.junit.vintage (應該是 JUnit 5)
作者: handsomeLin (DoGLin)   2019-12-28 14:57:00
hashset幾乎所有語言都無序吧 包括hashmap
作者: OriginStar   2019-12-27 17:09:00
官方文件說It makes no guarantees as to the iteration orderof the set; in particular, it does not guaranteethat the order will remain constant over time.沒有保證每次call都會傳回一致順序的內容
作者: vavamos (vavamos)   2019-12-26 20:18:00
無序
作者: ssccg (23)   2019-12-26 21:17:00
以API來說你不該期待Set內容是有順序的,即使實作可能變成有順序,HashSet的iterator就寫沒固定順序了有實作SortedSet的Set才會是有序的
作者: jej (晃奶大馬桶)   2019-12-26 21:29:00
你原本的概念是對的hashset在add的原始碼有呼叫hashcode在你的案例應該是string是final物件所以你不能自己刻hashcode試著用刻過hashcode的物件放進去hashset他應該會根據你的hashcode排序
作者: ssccg (23)   2019-12-26 21:39:00
以理論上來說,hash table是依自己的hash function來放而且這個hash function的值域可能依當前bucket數量而變動不一定是直接用java的hashCode()的值,當然順序不一定即使自訂了hashCode也一樣

Links booklink

Contact Us: admin [ a t ] ucptt.com