Scala—哈希代码的行为&;使用可变哈希集时等于

Scala—哈希代码的行为&;使用可变哈希集时等于,scala,functional-programming,Scala,Functional Programming,案例#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("Blac

案例#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)
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)  
案例#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: Set(scalaproj.Bear@7d4991ad, scalaproj.Bear@28d93b30)
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-案例#2-为什么定义hashCode方法时会调用三次-添加“bear1”时调用两次,添加“bear2”时调用一次

2-案例#1-为什么在没有定义哈希代码的情况下根本不调用equals方法-即使在案例#2中调用了它。(即使对于case类,通常在所有情况下都会调用重写的equals方法)

关于问题2:

当两个对象具有相同的
hashCode
时,将调用
equals
方法来解决“tie”。因为在这种情况下散列是不同的,所以不会调用equals

关于问题1:

实际上,当定义
HashSet
时,调用
bear1
bear2
hash
方法,因为它们的计算值相同(即100),也将调用
equals

hashCode
方法的额外调用是因为
println(setBears)
。它显示哈希集中每个对象的哈希

因此,在创建HashSet时,它会添加两个
hashCode
调用(每个熊一个)和一个
等于
调用,以解决关于问题2:

当两个对象具有相同的
hashCode
时,将调用
equals
方法来解决“tie”。因为在这种情况下散列是不同的,所以不会调用equals

关于问题1:

实际上,当定义
HashSet
时,调用
bear1
bear2
hash
方法,因为它们的计算值相同(即100),也将调用
equals

hashCode
方法的额外调用是因为
println(setBears)
。它显示哈希集中每个对象的哈希


因此,在创建HashSet时,它会添加两个
hashCode
调用(每个熊一个)和一个
equals
调用来解决这个问题

如果hash代码不同,则不必调用equals方法。重新表述@Bubletan,不同的hash可以确保不同的对象。第一个实现总是为不同的实例提供不同的哈希值。因此,equals永远不会被调用。谢谢你的回答。我想你们都回答了第一个问题。因为hashCode没有被覆盖(用户定义),所以使用默认值。此默认哈希代码为bear1和bear2返回不同的结果,在这种情况下,根本不需要调用equals方法。如果哈希代码不同,则不必调用equals方法。重新表述@Bubletan,不同的哈希可确保不同的对象。第一个实现总是为不同的实例提供不同的哈希值。因此,equals永远不会被调用。谢谢你的回答。我想你们都回答了第一个问题。因为hashCode没有被覆盖(用户定义),所以使用默认值。此默认哈希代码为bear1和bear2返回不同的结果,在这种情况下,根本不需要调用equals方法。谢谢您的回答。是的,我可以看到,因为在#2中hashCode的结果是一致的,所以调用了equals方法。另外,我可以看到println(setbeears)实际上正在调用hashCode方法。谢谢你的回答。是的,我可以看到,因为在#2中hashCode的结果是一致的,所以调用了equals方法。另外,我可以看到println(setBears)实际上正在调用hashCode方法。