作者obelisk0114 (追風箏的孩子)
看板java
標題[語法] 相同的物件們放到 HashSet 取出的順序
時間Thu Dec 26 19:43:06 2019
之前一直認為相同的物件們放到 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://webptt.com/m.aspx?n=bbs/java/M.1577360604.A.C02.html
1F:推 vavamos: 無序 12/26 20:18
2F:→ ssccg: 以API來說你不該期待Set內容是有順序的,即使實作可能變成 12/26 21:17
3F:→ ssccg: 有順序,HashSet的iterator就寫沒固定順序了 12/26 21:17
4F:→ ssccg: 有實作SortedSet的Set才會是有序的 12/26 21:25
5F:推 jej: 你原本的概念是對的 12/26 21:29
6F:→ jej: hashset在add的原始碼有呼叫hashcode 12/26 21:29
7F:→ jej: 在你的案例應該是string是final物件 12/26 21:29
MockMvc 得到的 http response, 應該不是 final 物件
8F:→ jej: 所以你不能自己刻hashcode 12/26 21:29
9F:→ jej: 試著用刻過hashcode的物件放進去hashset 12/26 21:29
10F:→ jej: 他應該會根據你的hashcode排序 12/26 21:29
11F:→ ssccg: 以理論上來說,hash table是依自己的hash function來放 12/26 21:39
12F:→ ssccg: 而且這個hash function的值域可能依當前bucket數量而變動 12/26 21:40
13F:→ ssccg: 不一定是直接用java的hashCode()的值,當然順序不一定 12/26 21:40
14F:→ ssccg: 即使自訂了hashCode也一樣 12/26 21:47
之前有測過 new HashSet<>(p) 來給定初始 size 大於 m
結果也是不一定順序相同
看來內部 bucket 數量和初始大小的關係沒有完全相關
15F:推 OriginStar: 官方文件說 12/27 17:09
16F:→ OriginStar: It makes no guarantees as to the iteration order 12/27 17:10
17F:→ OriginStar: of the set; in particular, it does not guarantee 12/27 17:10
18F:→ OriginStar: that the order will remain constant over time. 12/27 17:10
19F:→ OriginStar: 沒有保證每次call都會傳回一致順序的內容 12/27 17:11
※ 編輯: obelisk0114 (73.35.172.61 美國), 12/27/2019 17:50:00
20F:推 handsomeLin: hashset幾乎所有語言都無序吧 包括hashmap 12/28 14:57