我正在用 Kotlin 研究地图,并决定运行此代码:
fun main() {
data class KeyClass(val equals: String, val hash: Int) {
override fun equals(other: Any?): Boolean {
return this.equals == (other as KeyClass).equals
}
override fun hashCode(): Int {
return hash
}
override fun toString(): String {
return "($equals,$hash)"
}
}
// collision, since their hashes are the same but they are not equal
val a1 = KeyClass("a", 1)
val a2 = KeyClass("b", 1)
val map = HashMap<KeyClass, String>()
map[a1] = "value1"
println(map)
map[a2] = "value2"
println(map)
val map2 = mutableMapOf<KeyClass, String>()
map2[a1] = "value1"
println(map2)
map2[a2] = "value2"
println(map2)
}
这让我:
{(a,1)=value1}
{(a,1)=value1, (b,1)=value2}
{(a,1)=value1}
{(a,1)=value1, (b,1)=value2}
我以为HashMap
的{{3}}。然后当我尝试使用 Kotlin 的 mutableMapOf
LinkedHashMap
时,我也没有遇到任何碰撞。
问题:
Map
实现中最常见的碰撞行为是什么?答案 0 :(得分:4)
您所说的列表是内部实现细节。你无法判断*这是地图内部发生的事情,这就是封装的重点。
观察碰撞的唯一方法是计时。因此,制作一百万个字符串,将它们放入映射中,然后对其中的条目运行 .containsKey()
几次。
然后,重复练习,但这一次,制作一百万个碰撞的对象(相同的哈希码)。然后,再次对其中的条目运行 .containsKey()
几次。
您会注意到第二个操作返回完全相同的答案,但是运行速度慢得多,这是您要观察的唯一事情。
*) 通过时间观察,您可以推测它,但仅此而已。
答案 1 :(得分:0)
你确实发生了碰撞。可能结果并不是你所期望的。您遇到了 hashCode 冲突,这只会减慢地图的插入和检索时间。我认为您希望地图只包含 1 个条目,但即使哈希码与键的等号匹配,但不匹配,因此您仍然在映射中放置 2 个不同的键,生成 2 个条目。