Правило 1 при реализации equals (): реализовать hashCode () одновременно.См. Переопределение equals и hashCode в Java
В первом примере вы создаете изменяемый набор, который вызывает hashCode для установки хеш-таблицы.
Вво-вторых, вы используете неизменяемый набор с одной записью, поэтому Scala на самом деле использует оптимизированную версию Set под названием 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)
}
}
Хеш-код не вызывается.Также есть 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 в equals, и получим:
mutable
hashCode=30936685
hashCode=26956691
mutableSet=Set(test) contains=false
immutable
equals=test
immutableSet=Set(test) contains=true
, который объясняет, почему mutable.contains () не работает правильно.Он ищет объект в неправильной записи хеш-таблицы, equals () даже не вызывается.И, что неудивительно, он не находит его.
Вы можете реализовать hashCode, используя text.hashCode:
override def hashCode: Int = text.hashCode