看板 java 關於我們 聯絡資訊
之前一直認為相同的物件們放到 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) -- ◢▇▆◣▂ 這就是人蔘●● ︷ ︷ ▅◤ ◢▆◣ ▂▃\ ██ _▏ ︽ ※※※※ ︽ ︽ ︿ ︽ ︿ ︿ ﹦︻ ▆▆▆ ︿ ※※※※ ︿ ︿ ︿ ︿ ︿ ︳﹣﹦ ﹣﹦ ︽ ※※※※ ︽ ︽ ︿ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 73.35.172.61 (美國) ※ 文章網址: https://www.ptt.cc/bbs/java/M.1577360604.A.C02.html
vavamos: 無序 12/26 20:18
ssccg: 以API來說你不該期待Set內容是有順序的,即使實作可能變成 12/26 21:17
ssccg: 有順序,HashSet的iterator就寫沒固定順序了 12/26 21:17
ssccg: 有實作SortedSet的Set才會是有序的 12/26 21:25
jej: 你原本的概念是對的 12/26 21:29
jej: hashset在add的原始碼有呼叫hashcode 12/26 21:29
jej: 在你的案例應該是string是final物件 12/26 21:29
MockMvc 得到的 http response, 應該不是 final 物件
jej: 所以你不能自己刻hashcode 12/26 21:29
jej: 試著用刻過hashcode的物件放進去hashset 12/26 21:29
jej: 他應該會根據你的hashcode排序 12/26 21:29
ssccg: 以理論上來說,hash table是依自己的hash function來放 12/26 21:39
ssccg: 而且這個hash function的值域可能依當前bucket數量而變動 12/26 21:40
ssccg: 不一定是直接用java的hashCode()的值,當然順序不一定 12/26 21:40
ssccg: 即使自訂了hashCode也一樣 12/26 21:47
之前有測過 new HashSet<>(p) 來給定初始 size 大於 m 結果也是不一定順序相同 看來內部 bucket 數量和初始大小的關係沒有完全相關
OriginStar: 官方文件說 12/27 17:09
OriginStar: It makes no guarantees as to the iteration order 12/27 17:10
OriginStar: of the set; in particular, it does not guarantee 12/27 17:10
OriginStar: that the order will remain constant over time. 12/27 17:10
OriginStar: 沒有保證每次call都會傳回一致順序的內容 12/27 17:11
※ 編輯: obelisk0114 (73.35.172.61 美國), 12/27/2019 17:50:00
handsomeLin: hashset幾乎所有語言都無序吧 包括hashmap 12/28 14:57