HashTable和HashMap键值如何存储在内存中?
我知道有一种散列技术应用于一个键,用于将其值存储在内存地址中。
但是我不明白碰撞是怎么发生的 ? Java使用哪种哈希算法来创建内存空间 ? 是MD5吗?
HashMap
的基本思想是这样的:
-
HashMap
实际上是一个包含Key和Value的特殊对象数组。 - arrays有一些桶(槽),比如说16。
- 散列算法由每个对象具有的
hashCode()
方法提供。 因此,在编写新Class
,应该注意正确的hashCode()
和equals()
方法实现。 默认值(Object
类)将内存指针作为数字。 但这对我们想要使用的大多数类都不好。 例如,String
类使用一种算法,该算法从字符串中的所有字符生成哈希 – 想象如下:hashCode = 1.char + 2.char + 3.char...
(简化)。 因此,两个相等的字符串,即使它们位于内存中的不同位置,也具有相同的hashCode()
。 -
hashCode()
的结果,比如说“132”,那么如果我们有一个很大的数组,那么应该存储对象的存储桶数量。 但我们没有,我们的只有16桶。 所以我们使用明显的计算'hashcode % array.length = bucket'
或'132 mod 16 = 4'
并将Key-Value对存储在4号桶中。 -
- 如果还没有其他配对,那没关系。
- 如果有一个Key等于我们拥有的Key,我们删除旧的。
- 如果存在另一个键值对(碰撞),我们将旧的键值对链接到链接列表中。
- 如果支持数组变得太满,那么我们必须创建太多的链表,我们创建一个双倍长度的新数组,重新散列所有元素并将它们添加到新数组中,然后我们处理旧数组。 这很可能是
HashMap
上最昂贵的操作,所以如果你以前知道它,你想告诉你的Maps
你将使用多少桶。 - 如果有人试图得到一个值,他提供一个密钥,我们哈希,修改它,然后通过潜在的链表进行完全匹配。
一张图片,由维基百科提供:
在这种情况下,
- 有一个256桶的数组(编号,当然,0-255)
- 有五个人。 在通过
mod 256
之后,它们的哈希码指向arrays中的四个不同的槽。 - 你可以看到Sandra Dee没有一个免费的插槽,所以她被约翰史密斯束缚了。
现在,如果您试图查找Sandra Dee的电话号码,您可以将她的名字哈希,将其修改为256,然后查看存储桶152.在那里您可以找到John Smith。 那不是桑德拉,再看看……啊哈,桑德拉在约翰之后被束缚住了。
Hash
并不意味着Hashing
技术,如MD5 。 它是用于存储特定键的Object
的内存位置的HashCode 。
阅读:
- Java hashmap如何工作?
- HashMap如何在Java中工作
这对HashMap如何工作有一些更清晰的解释?
作为默认实现, Object
类中的hashCode()
函数返回内存地址作为哈希,它在HashTable
和HashMap
用作键。
在经过@Slanec的回答后,确实看到了Java-8中的javadoc,因为有重大变化。 例如:’TREEIFY’,其中LinkedList转换为TreeMap,以防达到每个桶的阈值条目数(当前为8)。