繁体   English   中英

斯卡拉匹配方法等于

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM