[英]HashCode in scala mutable collection
在這段代碼中
object Program1 extends App {
val set = scala.collection.mutable.Set( "Abc", "def")
set += "ghi"
}
因為在這種情況下set是可變的,這意味着它將向其自身添加元素,並且不會創建新的set,但是當我嘗試顯示set的hashCode()
時,如下所示:
object Program1 extends App {
val set = scala.collection.mutable.Set( "Abc", "def")
println(set.hashCode)
set += "ghi"
println(set.hashCode)
}
我希望println()
語句將輸出相同的哈希碼,但打印的結果不同,這是因為set對象未更改,而我們只是追加到現有set上,然后為什么hashcode會有所不同。
如果在scala中查看可變HashSet
hashCode
實現,您會發現它哈希了其所有內部元素。 散列時,我的scala版本最終出現在MurmurHash3.unorderedHash(...)
調用中。 可能與其他人有所不同。
如果您問為什么? 我猜這是因為Set("Abc", "def") != Set("Abc", "def", "ghi")
並且還與不可變的HashSet
實現對齊。 這是完全合理的,我不知道您為什么會這樣做。
更新
一些其他解釋來回答作者的評論
hashCode
都是關於平等的,而不是關於同一對象的。 規則是,如果兩個對象相等,則它們應返回相同的hashCode
。 如果不是,則最好返回不同的值(我說更好,因為仍然有可能通過碰撞返回相同的值)。 對於所有對象都是如此。
考慮以下代碼:
import scala.collection.mutable.Set
val s1 = Set(1)
val superSet = Set(s1)
println(superSet.contains(s1)) // prints true
println(superSet.contains(Set(1)) // still prints true
請注意,即使s1
和Set(1)
是內存中的兩個不同對象,它們都顯示為true。 這是因為它們的equals
和hashCode
返回相同的
現在,此實現存在一個小問題:
import scala.collection.mutable.Set
val superMap = scala.collection.mutable.Map.empty[Set[String], Boolean]
superMap += (set -> true)
println(superMap.contains(set)) // prints true
set += "ghi"
println(superMap.contains(set)) // prints false
println(superMap.contains(Set("Abc", "def"))) // still prints false
第二個println
打印false
。 這是因為Map
找不到密鑰,因為密鑰更改了其hashCode
,但是Map
仍然記住舊的密鑰。 第三println
仍然未通過檢查,因為即使包含hashCode
在Map
和Set("Abc", "def").hashCode
相同,套之后失敗的平等檢查。
這是一個眾所周知的問題,沒有好的解決方案,因此建議不要使用可變對象作為HashMap
的鍵。 通常,對於任何應用了hashCode
-check然后equality
-check的結構,都不應使用可變對象。 HashSet
同樣適用
此功能反映了所有hashCode()
和equals()
實現所推薦的功能:如果a1.equals(a2)
則a1.hashCode() == a2.hashCode()
。 在這里查看帖子以了解更多信息https://stackoverflow.com/a/256447/1154145
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.