HashMap 元素添加流程
在Java 1.8中,HashMap的元素添加流程:
- 计算键的哈希值:当调用
put(key, value)
方法时,首先会计算键(key)的哈希值,这个哈希值用来确定元素在内部数组中的位置。 - 确定位置:通过哈希值,HashMap确定元素应该放置在内部数组的哪个位置(桶)。
- 检查桶是否为空:HashMap每个桶内可以存放多个元素,因此需要检查所选桶是否为空。如果为空,直接将键值对添加到该桶中。
- 解决哈希冲突:如果所选桶不为空,可能发生哈希冲突,即不同键具有相同哈希值。在Java 1.8中,HashMap使用链表和红黑树(TreeMap)来解决哈希冲突。如果桶内的元素较少,HashMap将使用链表存储;如果桶内的元素较多,HashMap会将链表转换为红黑树以提高性能。
- 插入键值对:最终,HashMap将键值对插入到所选桶中,无论是在链表中还是红黑树中。
- 检查是否需要进行容量调整:在添加元素后,HashMap会检查当前的容量是否达到了某个阈值(负载因子)。如果超过了负载因子,HashMap会进行容量调整,即扩大内部数组的大小,以保持性能。
这些是HashMap元素添加的基本流程。Java 8的HashMap在解决哈希冲突时引入了红黑树,以提高性能,特别是在处理大型容器时。这种树结构的引入让HashMap的操作在平均情况下保持O(1)的时间复杂度。
HashMap 的查询流程
1、首先,根据要查询元素的键(Key) 通过哈希函数计算出哈希值(Hash Value) ,哈希函数实现源码如下:
注:这行源码的主要含义是把哈希码按位异或哈希码右移 16 位的操作,让高位与低位混合,可以更好地分散元素在哈希表中的位置,减少哈希冲突的发生。
2、使用哈希值与哈希表的容量进行与操作 (hash & (table.length-1)),得到元素在哈希表中的位置,即索引。
3、在该索引位置上,如果没有任何元素,则说明哈希表中不存在该键对应的元素,查询失败。
4、如果该索引位置上存在元素 (可能是一个元素或者一个链表/红黑树),则进行以下操作:
如果仅有一个元素,则判断该元素的键是否与要查询的键相等。如果相等,则返回该元素的值:否则查询失败。
如果存在链表或红黑树,则遍历链表或红黑树,逐个比较键的值,找到与要查询的键相等的元素,并返回对应的值。
HashMap 的主要查询流程是:
1、根据哈希函数得到 key 的哈希值
2、根据哈希值得到哈希表中的存储位置
3、查询位置上是否有元素
如果没有元素,返回 null.
如果有元素,逐个对比 key,如果 key 对的上就返回对应的 value,否则返回 null