Luo*_*inh 1 java hash scala hashmap
我有两个问题:
为什么HashMap使用密钥的内存地址作为映射条目的标识符,即桶.据我所知,只要我覆盖hashCode(),密钥的哈希码将用作桶ID.
HashMap当密钥在下面的代码中发表评论时,为什么会更新:
object Equals {
def main(args: Array[String]) {
val pointX = new Point2(1, 1)
val pointY = new Point2(2, 1)
val pointZ = new Point2(4, 4)
val map = HashMap(pointX -> "X", pointY -> "Y")
println(s"Map before: $map")
//Map before: Map(oo.Point2@20 -> X, oo.Point2@3f -> Y)
pointX.move(3, 3)
println(s"Map after: $map")
//Map after: Map(oo.Point2@80 -> X, oo.Point2@3f -> Y)
println(map(pointZ))
}
}
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么HashMap使用密钥的内存地址作为映射条目的标识符
它没有.它使用密钥的哈希码.(为什么你认为它使用内存地址?).
如果你想知道为什么键是这样的oo.Point2@20,那是因为你没有toString()在课堂上覆盖Point.
为什么在密钥变异时HashMap会更新
因为HashMap不会复制您用作键的对象; 它只存储对关键对象的引用.如果在将密钥放入后修改密钥HashMap,则HashMap还会看到更改.
HashMap如果密钥对象以一种方式更改其hashCode()方式将返回不同的值(因为该条目可能突然出现在错误的桶中),这将使您陷入困境.
不要修改在a中用作键的对象HashMap,因为这会导致奇怪的问题(例如,对象可能看起来像是从地图中消失了).在a中用作键的对象HashMap应该是不可变的.