Scala - 使用可变HashSet时hashCode和equals的行为

use*_*rix 1 functional-programming scala

CASE#1-我有以下课程:

class Bear (val aName: String) { 
   def getName: String = aName
   override def equals (a : Any) : Boolean = { println("Test Equals"); true}      
 }
Run Code Online (Sandbox Code Playgroud)

如果我运行以下代码,我会得到以下结果:

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)
Run Code Online (Sandbox Code Playgroud)

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 }
 }
Run Code Online (Sandbox Code Playgroud)

并运行相同的代码我得到以下结果:

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)  
Run Code Online (Sandbox Code Playgroud)

我的两个问题:

1- CASE#2-为什么定义hashCode方法时,它被调用三次 - 添加"bear1"时两次,添加"bear2"时一次

2- CASE#1 - 为什么在未定义hashCode时根本不调用equals方法 - 尽管在CASE#2中调用了它.(即使对于案例类,在所有情况下通常都会调用重写的equals方法)

Raq*_*ães 5

关于问题#2:

当两个对象具有相同的时hashCode,equals将调用该方法来解决'tie'问题.因为在这种情况下哈希是不同的,所以不会调用equals

关于问题#1:

实际上发生的事情是,当HashSet定义时,hash方法bear1bear2被调用,因为它们评估为相同的值(即100),equals也将被调用.

对该hashCode方法的额外调用是因为println(setBears).它显示了hashset中每个对象的哈希值.

因此,在创建HashSet时,它最多可以添加两个hashCode呼叫(每个熊一个)和一个equals呼叫来解决这个问题