[英]Scala match in equals method
I'm new to Scala, but have a decent Java background. 我是Scala的新手,但是拥有不错的Java背景。 My question is about overriding the equals method in Scala. 我的问题是关于重写Scala中的equals方法。 The following example is from the Scala cookbook: 以下示例来自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
}
}
My question is why we need 我的问题是为什么我们需要
that.canEqual(this)
My understanding is that that code will only be executed if 'that' is a person. 我的理解是,只有在“那个”是一个人的情况下,该代码才会被执行。 So, why the extra call to isInstanceOf? 那么,为什么要额外调用isInstanceOf?
that.canEqual(this)
is not redundant. that.canEqual(this)
不是多余的。 It is necessary in case that
is an instance of a subclass of Person
that has defined it's own equality (and it's own canEqual
method). 如果这是Person
子类的一个实例,该实例定义了它自己的相等性(并且它是自己的canEqual
方法) that
则很有必要。
this.canEqual(that)
on the other hand would be redundant. this.canEqual(that)
将是多余的。
The main purpose is to ensure that the equality relation is valid in both directions between an instance of Person
and potentially a subclass of Person
that may have it's own implementation of equals. 主要目的是确保相等关系在 Person
实例与可能具有自己的equals实现的Person
子类之间的两个方向上均有效。
Suppose I have: 假设我有:
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
More detailed explanation link provided by pedrofurla in the comments: http://www.artima.com/pins1ed/object-equality.html pedrofurla在评论中提供了更详细的解释链接: http : //www.artima.com/pins1ed/object-equality.html
Two different objects from two separate classes can have the same hash code; 来自两个不同类的两个不同对象可以具有相同的哈希码。 you therefore cannot say that two objects are equal based on their hash code alone. 因此,您不能仅凭其哈希码就说两个对象相等。 For example, a Dog
with yellow fur and a loud bark might have hashCode
of 20011 because of the way a Dog
defines hashCode
; 例如, Dog
,黄色的皮毛和一个响亮的吠声可能hashCode
的20011的,因为路上Dog
定义hashCode
; a RocketShip
designed to fly to Saturn might also have a hashCode
of 20011 for a very unrelated reason. 出于非常不相关的原因,设计要飞往土星的RocketShip
也可能具有20011的hashCode
。 Clearly, these are two very different objects. 显然,这是两个截然不同的对象。 If, however, two Dogs
or two RocketShips
have the same hash code then it is probably* safe to assume they're equivalent objects: it wouldn't make any sense to have to have two equivalent objects (eg, two Dogs
with yellow fur and loud barks) have two different hash codes, and it wouldn't make sense to have two different objects of the same type (eg, one Dog
with black fur, another with brown fur) have the same hash code. 但是,如果两个Dogs
或两个RocketShips
具有相同的哈希码,则可以很安全地假定它们是等效的对象:必须具有两个等效的对象(例如,两个带有黄色毛皮的Dogs
毫无意义)和大声的吠声)具有两个不同的哈希码,并且使两个不同类型的对象(例如,一个黑色毛皮的Dog
,另一个棕色毛皮的Dog
)具有相同的哈希码是没有意义的。 The isInstanceOf
check lets you ensure that you're dealing with two objects of the same type: the hash code check allows you to quickly assess whether or not two objects should be equivalent. isInstanceOf
检查使您可以确保处理两个相同类型的对象:哈希码检查使您可以快速评估两个对象是否等效。
(*: If there are a finite number of hash codes and an infinite combination of attributes producing unique Dogs
, then there will inevitably be hash code collisions. Even the isInstanceOf
check isn't sufficient, but is probably good enough for most cases and hence in the cookbook as an example.) (*:如果存在数量有限的哈希码和属性的无限组合产生唯一的Dogs
,那么不可避免地会发生哈希码冲突。即使isInstanceOf
检查也是不够的,但对于大多数情况来说可能就足够了,因此以食谱为例。)
Pitfall #2: Changing equals without also changing hashCode. 陷阱2:在不更改hashCode的情况下更改等于。 If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result 如果根据equals方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果
In short, two equal objects must have the same hash code to fulfill the method's contract (but nowhere does it say that two objects with equal hash codes must be equal!) 简而言之,两个相等的对象必须具有相同的哈希码才能满足方法的约定(但没有任何地方说具有相等的哈希码的两个对象必须相等!)
Edit 2 As you have a Java background, you're likely used to seeing something of the following. 编辑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;
}
The code sample you've given is doing (roughly) the same thing, with the hashCode
check substituting for an equality check. 您提供的代码示例在做(大致)相同的事情,用hashCode
检查代替了相等检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.