Scala Equality和HashCode

 lookzana 发布于 2023-02-09 18:34

深度Scala在mutability和上呈现此代码equality.

class Point2(var x: Int, var y: Int) extends Equals {
def move(mx: Int, my: Int) : Unit = {
  x = x + mx
  y = y + my
}
override def hashCode(): Int = y + (31*x)

def canEqual(that: Any): Boolean = that match {
  case p: Point2 => true
  case _ => false
}
override def equals(that: Any): Boolean = {
def strictEquals(other: Point2) =
  this.x == other.x && this.y == other.y
  that match {
    case a: AnyRef if this eq a => true
    case p: Point2 => (p canEqual this) && strictEquals(p)
     case _ => false
  }
}
}

然后,它执行评估.

scala> val x = new Point2(1,1)
x: Point2 = Point2@20
scala> val y = new Point2(1,2)
y: Point2 = Point2@21
scala> val z = new Point2(1,1)
z: Point2 = Point2@20

接下来,HashMap创建一个.

scala> val map = HashMap(x -> "HAI", y -> "WORLD")
map: scala.collection.immutable.HashMap[Point2,java.lang.String] =
Map((Point2@21,WORLD), (Point2@20,HAI))

scala> x.move(1,1)

scala> map(y)
res9: java.lang.String = WORLD

据我所知,自从发生变异后map(x)将会返回.由于突变,重新计算了hashCode .结果,当检查是否在,没有地图的匹配是新的.NoSuchElementExceptionxxx.move(1,1xmaphashCodexhashCode

scala> map(x)
java.util.NoSuchElementException: key not found: Point2@40
...

由于zequals(value)最初插入xHashMap,以及hashCode为什么抛出异常?

scala> map(z)
java.util.NoSuchElementException: key not found: Point2@20

编辑在我看来,这个例子显示了命令式编程的复杂性(坏).

1 个回答
  • 因为Map仍然用于x测试相等性.

    这是发生的事情:

    你使用x键作为键插入地图中,此时的hashCode是#x.大.

    你改变了一些值x,#x现在消失了,新的hashCode是#x'.

    您尝试查找x与地图关联的值.地图获取hashCode:#x'.它在地图中不存在(因为在插入时它是#x).

    zx最初的相同值创建.

    你查找与之关联的值z.地图发现的的hashCode值z(因为它是#X),但随后调用equalszx(同一个实例,你使用过程中的第一步,插入值).false你搬家后就得到了x!

    映射保留对密钥实例的引用,并使用它来测试equals何时get,但它从不重新计算hashCode.

    2023-02-09 18:37 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有