好吧,我最近读了很多关于HashMap
的文章,我认为有些人把它弄得比实际情况更加混乱。我想知道这个程序是否正确。
所以当你有一个Key
和Value
时,例如出生于1805-02-13年的彼得迪里克莱,在这种情况下Key
就是"Peter Dirichlet"
和Value
,"1805-02-13"
。
第一步是在Key
上使用hash函数,即"Peter Dirichlet"
。假设hash函数将此生成到bucket nr5
。这意味着在这个特定的bucket中,在index5
上,键/值对"Peter Dirichlet","1805-02-13"
将被存储。
因此,如果我们想检索这个信息,我们使用get("Peter Dirichlet")
并使用hash函数,就会找到索引号,并找到键/值对peter dirichlet 1805-02-13。
然后是碰撞。假设我们现在有"Leo Euler"
出生"1783-09-18"
。由于某种原因,我们的hash函数将宝贵的Leo也放在索引号5
中由于键值与peter dirichlet不同,因此不会有替换项。
现在,在“桶”第五,我们有利奥欧拉和彼得迪里克莱。
如果我们现在想要检索Leo,我们使用get("Leo Euler")
,hash函数将指向bucket 5。”哈什马说:“砰”的一声,“这里发生了碰撞”。
然后我们将遍历这些对象,直到找到"Leo Euler".equals("Leo Euler")
。所以它会得到key.equals(key)
?
因此,对于true
我们不会"Peter Dirichlet"
,而对于leo我们会true
,并返回键/值对。
这是对HashMap
的正确解释吗?
最佳答案
是的,这是正确的解释.hashcode()
(对于java,与其他编程语言等价)是不够的。有可能发生碰撞。它将遍历bucket,并对每个元素将查询(一个键)与该键值对的键进行比较。当然,从找到正确的键的那一刻起,就会返回相应的值。如果在bucket中找不到密钥,我们知道它不在hashmap中。
这就是为什么.equals
和.hashcode
之间有一个契约:如果a.equals(b)
,那么a
的hashcode必须等于b
:a.hashcode() == b.hashcode()
。注意,相反的情况并非如此:拥有相同的hashcode并不意味着对象是等价的。
对于您的问题,可能有一点小小的说明:HashMap的内部数组不是由键值对组成的,而是由键值对的集合组成的在许多情况下,这要么是LinkedList
要么是ArrayList
一些实现使用二叉搜索树,尽管通常不会有太大的回报:毕竟使用一个好的散列函数应该可以减少冲突的数量。
关于algorithm - Hashmap过程来解决冲突,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34704441/