規則1實現equals()時:同時實現hashCode()。請參閱Overriding equals and hashCode in Java
在第一個示例中,您將創建一個可調集合,它將調用hashCode來設置哈希表。
第二,你使用一個條目的不可變集合,所以Scala實際上使用集合的優化版本,稱爲Set1。 Set1.contains()只是直接使用equals()比較一個條目和傳入的元素。這看起來像:
/** An optimized representation for immutable sets of size 1 */
@SerialVersionUID(1233385750652442003L)
class Set1[A] private[collection] (elem1: A) extends Set[A] with Serializable {
override def size: Int = 1
def contains(elem: A): Boolean =
elem == elem1
def + (elem: A): Set[A] =
if (contains(elem)) this
else new Set2(elem1, elem)
def - (elem: A): Set[A] =
if (elem == elem1) Set.empty
else this
def iterator: Iterator[A] =
Iterator(elem1)
override def foreach[U](f: A => U): Unit = {
f(elem1)
}
}
沒有調用hashCode。還有一個Set2,Set3和Set4。如果我們改變
所以你的代碼是:
class Test(val text:String){
override def equals(obj:Any) = {
println("equals=" + obj)
obj match {
case t: Test => if (t.text == this.text) true else false
case _ => false
}}
override def hashCode(): Int = {
println("hashCode=" + super.hashCode())
super.hashCode()
}
override def toString = text
}
println("mutable")
val mutableSet:scala.collection.mutable.Set[Test] = scala.collection.mutable.Set.empty
mutableSet += new Test("test")
println("mutableSet=" + mutableSet + " contains=" + mutableSet.contains(new Test("test")))
println("immutable")
var immutableSet:scala.collection.immutable.Set[Test] = scala.collection.immutable.Set.empty
immutableSet += new Test("test")
println("immutableSet=" + immutableSet + " contains=" + immutableSet.contains(new Test("test")))
添加一個hashCode,並在平等的一個println,輸出是:
mutable
hashCode=30936685
hashCode=26956691
mutableSet=Set(test) contains=false
immutable
equals=test
immutableSet=Set(test) contains=true
這解釋了爲什麼mutable.contains( )工作不正常。它在錯誤的哈希表項中查找對象,equals()甚至沒有被調用。毫不奇怪,它沒有找到它。
可以使用text.hashCode實現的hashCode:
override def hashCode: Int = text.hashCode
正如Matthew所說:-) –
謝謝,我還沒有意識到,有大小爲1的不變集的特殊情況。 – Stefan