如何解决`set.contains` 在 Scala 中是如何工作的?
考虑以下代码:
import scala.collection.mutable
case class A(b: Int) {
override def equals(obj: Any): Boolean = {
println("called")
obj match {
case o: A => b == o.b
case _ => false
}
}
}
val set = mutable.Set.empty[A]
val a1 = A(1)
set.add(a1)
println(set.contains(A(1)))
println(set.contains(A(2)))
为什么 set.contains
的第二次调用没有打印出“已调用”?有人能解释一下 set 如何识别两个相等的对象吗?
解决方法
正如@LuisMiguelMejíaSuárez 在评论中提到的,可变 Set
由 HashSet
支持。它在 What issues should be considered when overriding equals and hashCode in Java?
当 a.equals(b) 时,a.hashCode() 必须与 b.hashCode() 相同。
这是因为 hashCode
是先验检查,失败时 equals
肯定也会失败。
从 What code is generated for an equals/hashCode method of a case class? 我们可以得出结论,对于案例类,hashCode
和 equals
被案例类覆盖,使用 productPrefix
表示案例类中的第一组元素.例如,如果我们有:
case class c(a: A)(b: B)
hashCode
和 equals
将仅基于 a
计算。在您的情况下,hasCode
方法是基于 gender
计算的,这对于 Person(1)
和 Person(2)
是不同的。因此没有必要检查 equals
,它假定也会失败。
来自What issues should be considered when overriding equals and hashCode in Java?的提示
在实践中:
如果你覆盖了一个,那么你应该覆盖另一个。
使用与计算 equals() 相同的一组字段来计算 hashCode()。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。