案例类哈希代码和等于将覆盖可选属性



如果所有属性都是可选的,如何覆盖哈希码和等于方法,我在下面尝试,编写哈希代码和等于的更好方法

case class A(id: Option[String], name: Option[String]){
override def hashCode(): Int = ???
override def canEqual(a: Any) = a.isInstanceOf[A]
override def equals(obj: Any): Boolean = obj match {
case obj: A => {
obj.canEqual(this) && this.id == obj.id && this.name == obj.name
}
case _ => false
}
}

如果你不装箱原语或空值,你可以没有奢侈的平等。

这可以保存一些空检查和实例/检查广播。

scala> case class C(id: Option[String], name: Option[String]) {
| override def equals(other: Any) = other match { case c: C => cmp(id, c.id) && cmp(name, c.name) case _ => false }
| private def cmp(x: Option[String], y: Option[String]): Boolean =
| if (x eq None) y eq None else !(y eq None) && x.get.equals(y.get)
| }
defined class C
scala> val x = C(Option("king"), Option("kong"))
x: C = C(Some(king),Some(kong))
scala> val y = C(Option("king"), Option("kong"))
y: C = C(Some(king),Some(kong))
scala> x == y
res0: Boolean = true
scala> val y = C(Option("king"), Option("king"))
y: C = C(Some(king),Some(king))
scala> x == y
res1: Boolean = false

但:

scala> val y = C(Option("king"), Some(null))
y: C = C(Some(king),Some(null))
scala> x == y
res2: Boolean = false
scala> y == x
java.lang.NullPointerException
at C.cmp(<console>:4)
at C.equals(<console>:2)
... 28 elided
scala> val y = C(Option("king"), null)
y: C = C(Some(king),null)
scala> x == y
java.lang.NullPointerException
at C.cmp(<console>:4)
at C.equals(<console>:2)
... 28 elided

避免使用无哈希代码并没有多大好处,这只是"None".##

说明一些比较的损失:

scala> :pa
// Entering paste mode (ctrl-D to finish)
case class C(id: Option[String], name: Option[Any]) {
override def equals(other: Any) = other match { case c: C => cmp(id, c.id) && cmp(name, c.name) case _ => false }
private def cmp[A](x: Option[A], y: Option[A]) = if (x eq None) y eq None else !(y eq None) && x.get.equals(y.get)
}
// Exiting paste mode, now interpreting.
defined class C
scala> val x = C(Option("king"), Option('k'))
x: C = C(Some(king),Some(k))
scala> val y = C(Option("king"), Option('k'.toInt))
y: C = C(Some(king),Some(107))
scala> x == y
res19: Boolean = false
scala> case class K(id: Option[String], name: Option[Any])
defined class K
scala> K(Option("king"), Option('k')) == K(Option("king"), Option('k'.toInt))
res20: Boolean = true

最新更新