CASE#1-我有以下课程:
class Bear (val aName: String) {
def getName: String = aName
override def equals (a : Any) : Boolean = { println("Test Equals"); true}
}
如果我运行以下代码,我会得到以下结果:
import scala.collection.mutable.HashSet
val bear1 = new Bear("Black")
val bear2 = new Bear("Black")
val setBears: HashSet[Bear] = HashSet (bear1,bear2)
println(setBears)
res: Set(scalaproj.Bear@7d4991ad, scalaproj.Bear@28d93b30)
CASE#2-但是,当我将hashCode方法添加到类
时class Bear (val aName: String) {
def getName: String = aName
override def equals (a : Any) : Boolean = { println("Test Equals"); true}
override def hashCode() = { println("Test Hash");100 }
}
并运行相同的代码,我得到以下结果:
import scala.collection.mutable.HashSet
val bear1 = new Bear("Black")
val bear2 = new Bear("Black")
val setBears: HashSet[Bear] = HashSet (bear1,bear2)
println(setBears)
res: Test Hash
Test Hash
Test Equals
Test Hash
Set(scalaproj.Bear@64)
我的两个问题:
1- CASE#2-为什么定义hashCode方法时,它被调用三次 - 添加“bear1”时两次,添加“bear2”时一次
2- CASE#1 - 为什么在未定义hashCode时根本不调用equals方法 - 尽管在CASE#2中调用了它。 (即使对于案例类,在所有情况下通常都会调用重写的equals方法)
答案 0 :(得分:5)
关于问题#2:
如果两个对象具有相同的hashCode
,则会调用equals
方法来解决“{tie}”问题。因为在这种情况下哈希是不同的,所以不会调用equals
关于问题#1:
实际上发生的事情是,当定义HashSet
时,会调用hash
和bear1
的{{1}}方法,因为它们会评估为相同的值(即100),bear2
也将被调用。
对equals
方法的额外调用是因为hashCode
。它显示了散列集中每个对象的散列。
因此,在创建HashSet时,它最多可以添加两个println(setBears)
个调用(每个承载一个)和一个hashCode
调用来解决这个问题