[英]Scala match in equals method
我是Scala的新手,但是拥有不错的Java背景。 我的问题是关于重写Scala中的equals方法。 以下示例来自Scala食谱:
class Person (name: String, age: Int) {
def canEqual(a: Any) = a.isInstanceOf[Person]
override def equals(that: Any): Boolean =
that match {
case that: Person => that.canEqual(this) && this.hashCode == that.hashCode
case _ => false
}
}
我的问题是为什么我们需要
that.canEqual(this)
我的理解是,只有在“那个”是一个人的情况下,该代码才会被执行。 那么,为什么要额外调用isInstanceOf?
that.canEqual(this)
不是多余的。 如果这是Person
子类的一个实例,该实例定义了它自己的相等性(并且它是自己的canEqual
方法) that
则很有必要。
this.canEqual(that)
将是多余的。
主要目的是确保相等关系在 Person
实例与可能具有自己的equals实现的Person
子类之间的两个方向上均有效。
假设我有:
class Person(...) {
... as defined, but without the `that.canEqual(this)` call
}
class Nobody extends Person {
// contrived, but valid definition
override def equals (that: Any) = false
... and some definition of hashCode that happens to produce same value
}
...
// then
new Person(...) == new Nobody // true
new Nobody == new Person(...) // false
// breaks equals by not being symmetric
pedrofurla在评论中提供了更详细的解释链接: http : //www.artima.com/pins1ed/object-equality.html
来自两个不同类的两个不同对象可以具有相同的哈希码。 因此,您不能仅凭其哈希码就说两个对象相等。 例如, Dog
,黄色的皮毛和一个响亮的吠声可能hashCode
的20011的,因为路上Dog
定义hashCode
; 出于非常不相关的原因,设计要飞往土星的RocketShip
也可能具有20011的hashCode
。 显然,这是两个截然不同的对象。 但是,如果两个Dogs
或两个RocketShips
具有相同的哈希码,则可以很安全地假定它们是等效的对象:必须具有两个等效的对象(例如,两个带有黄色毛皮的Dogs
毫无意义)和大声的吠声)具有两个不同的哈希码,并且使两个不同类型的对象(例如,一个黑色毛皮的Dog
,另一个棕色毛皮的Dog
)具有相同的哈希码是没有意义的。 isInstanceOf
检查使您可以确保处理两个相同类型的对象:哈希码检查使您可以快速评估两个对象是否等效。
(*:如果存在数量有限的哈希码和属性的无限组合产生唯一的Dogs
,那么不可避免地会发生哈希码冲突。即使isInstanceOf
检查也是不够的,但对于大多数情况来说可能就足够了,因此以食谱为例。)
编辑:看这里 :
陷阱2:在不更改hashCode的情况下更改等于。 如果根据equals方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果
简而言之,两个相等的对象必须具有相同的哈希码才能满足方法的约定(但没有任何地方说具有相等的哈希码的两个对象必须相等!)
编辑2由于您具有Java背景,因此您可能经常会看到以下内容。
public boolean equals(Object other) {
// I am a Dog. If they're not a dog, I can't be equal to them.
if (!(other instanceof Dog))
return false;
// If the other dog's properties are equal to my own, then we're equal.
if (...)
return true;
// If not, we're not equal.
else
return false;
}
您提供的代码示例在做(大致)相同的事情,用hashCode
检查代替了相等检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.