`set.contains` 在 Scala 中是如何工作的?
How `set.contains` works in 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
的第二次调用没有打印出“called”?有人可以解释一下 set 是如何识别两个对象相等的吗?
正如@LuisMiguelMejíaSuárez 在评论中提到的,可变 Set
由 HashSet
支持。 What issues should be considered when overriding equals and hashCode in Java?
对此进行了详细阐述
Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().
这是因为hashCode
是事前检查,如果失败equals
肯定也会失败
从 What code is generated for an equals/hashCode method of a case class? 我们可以得出结论,对于案例 classes hashCode
和 equals
被案例 classes 覆盖,使用 productPrefix
表示案例 class 中的第一组元素。例如,如果我们有:
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?
的提示
In practice:
If you override one, then you should override the other.
Use the same set of fields that you use to compute equals() to compute hashCode().
考虑以下代码:
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
的第二次调用没有打印出“called”?有人可以解释一下 set 是如何识别两个对象相等的吗?
正如@LuisMiguelMejíaSuárez 在评论中提到的,可变 Set
由 HashSet
支持。 What issues should be considered when overriding equals and hashCode in Java?
Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().
这是因为hashCode
是事前检查,如果失败equals
肯定也会失败
从 What code is generated for an equals/hashCode method of a case class? 我们可以得出结论,对于案例 classes hashCode
和 equals
被案例 classes 覆盖,使用 productPrefix
表示案例 class 中的第一组元素。例如,如果我们有:
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?
的提示In practice:
If you override one, then you should override the other.
Use the same set of fields that you use to compute equals() to compute hashCode().