HashMap的工作原理:
1、HashMap基于hashing原理工作,使用get()、put()方法获取和存储对象。具体过程如下:
当键值对传递给put方法时,HashMap会调用键对象的hashCode()方法,来计算hashcode,然后根据这个hashcode找到bucket(桶)位置来存储值对象;
当获取对象时,HashMap会通过键对象的equals()方法找到对应的键值对,返回对象。
HashMap处理哈希冲突的方式:
哈希冲突是指不同的键可能映射到哈希表的同一个位置(桶)。为了处理这种情况,HashMap采用了以下方法:
1、链表法(链地址法):这是HashMap处理哈希冲突的基本方法。当发生 哈希冲突时,HashMap会在冲突的位置形成一个链表,将具有相同索引的键值对依次链接起来。这样,即使多个键映射到同一个索引,也可以通过链表来区分和存储他们。在Java7及以前的版本中,HashMap完全依赖于链表法来处理哈希冲突。
2、红黑树法:为了优化性能,从Java8开始,HashMap引入了红黑树法来处理哈希冲突。当链表的长度超过一定阈值时,HashMap会将链表转换为红黑树。红黑树时一种自平衡的二叉树,它能够在O(logn)世界复杂度内完成查找、插入和删除操作,从而大大提高了HashMap的性能。需要注意的的是,当链表长度缩短到小于等于6时,红黑树会重新退化成链表,以保持HashMap的简洁和灵活性。
HashMap处理哈希冲突的流程示例:
1、插入操作:
1、计算键的哈希值,找到对应的桶。
2、如果桶为空,则直接插入新的键值对。
3、如果桶不为空,则检查哈希冲突。
① 如果时链表结构,遍历链表,通过equals()方法检查是否存在相同的键。若找到相同的键,则更新其对应的值;若未找到,则将新的键值对插入链表末尾。
②如果桶中元素已经转换为红黑树结构,则在红黑树中插入新节点,保持树的平衡性。
4、插入新节点后,检查建表长度。如果链表长度超过阈值(默认8),则将链表转换为红黑树。
2、查找操作:
1、计算键的哈希值,找到对应的桶。
2、如果桶为空,则返回null。
3、如果桶不为空,则根据桶中的数据结构(链表或红黑树)进行查找。
① 链表结构:遍历链表,通过equals方法逐个比较节点的键,找到匹配的节点并返回对应的值。
② 红黑树结构:在红黑树中通过二分查找找到目标节点,并返回对应的值。
3、删除操作:
1、计算键的哈希值,找到对应的桶。
2、在链表或红黑树中查找与键匹配的节点。
3、如果找到匹配的节点,则将其从链表或红黑树中删除。删除后,如果红黑树节点数量减少到阈值以下,树结构将退化为链表。