Scala普通类与Case类hashCode方法差异及文档表述疑问
问题解答
核心原因拆解
普通类的hashCode来源
普通类的hashCode()并非Scala为其自动生成,而是继承自Java的根类Object。所有Java/Scala对象都会继承Object类的默认hashCode()实现,该方法返回基于对象内存地址的哈希值——这就是调用普通类实例的hashCode()能得到数值的原因。case类的hashCode的特殊之处
Scala文档强调case类自动生成equals和hashCode,是因为这两个方法是基于类的所有成员变量计算而来,而非依赖内存地址:
- 两个成员变量完全相同的case类实例,
hashCode()结果一致,equals()会返回true - 普通类的默认实现则完全相反:即使成员变量相同,不同实例的
hashCode()也会因为内存地址不同而不一样,equals()也只会判断是否是同一个对象
代码验证
class Person_Regular(name: String) case class Person_CC(name: String) // case类:相同内容的实例哈希值一致 val cc1 = Person_CC("Joe") val cc2 = Person_CC("Joe") println(cc1.hashCode() == cc2.hashCode()) // 输出 true println(cc1.equals(cc2)) // 输出 true // 普通类:相同内容的不同实例哈希值不同 val reg1 = new Person_Regular("Joe") val reg2 = new Person_Regular("Joe") println(reg1.hashCode() == reg2.hashCode()) // 输出 false println(reg1.equals(reg2)) // 输出 false
为什么文档要强调case类的这两个方法?
在业务场景中,我们通常希望内容相同的对象被视为相等,比如作为Map的键、在集合中去重等。普通类的默认hashCode和equals完全无法满足这个需求,必须手动重写;而case类自动帮你实现了符合业务预期的版本,这也是它被广泛用于数据载体的原因之一。
内容的提问来源于stack exchange,提问作者M.G.
相关产品推荐
相关产品推荐

