HashMap集合底层数据结构
数据结构就是计算机存储数据的方式,就是把数据都放在那个位置,怎么放好查询
jdk1.8之前 是数组+链表,用链表主要解决哈希冲突(也就是通过 hashCode 方法计算的哈希值一样的话会导致数据放在数组里位置一样所以加上链表)。
当链表长度大于阈值(默认为 8 )并且当前数组的长度大于64时,此时此索引位置上的所有数据改为使用红黑树存储。
HashMap (是根据关键码值(Key value)而直接进行访问的数据结构) **的 Map 接口实现,是以 key-value 存储形式存在,即主要用来存放键值对。HashMap 的实现不是同步的,这意味着它不是线程安全的。它的 key、value 都可以为 null,此外,HashMap 中的映射不是有序的
补充:将链表转换成红黑树前会判断,即便阈值大于8,但是数组长度小于64,此时并不会将链表变为红黑树,而是选择逬行数组扩容。
HashMap 特点:
- 存储无序的。
- 键和值位置都可以是 null,但是键位置只能存在一个 null。
- 键位置是唯一的,是底层的数据结构控制的。
- jdk1.8 前数据结构是链表+数组,jdk1.8 之后是链表+数组+红黑树。
- 阈值(边界值)> 8 并且数组长度大于 64,才将链表转换为红黑树,变为红黑树的目的是为了高效的查询
面试问题
1,HashMap中hash函数是怎么实现的(也就是通过hash这个算法得到应该把新加的数据放在什么位置也就是得到个索引),
答:(1),无符号右移16位然后做异或运算(关于无符号右移16位不懂的话找一下二进制知识点)
(2),平方去中法
(3),伪随机数法
(4),取余数法(也就是数据对应的哈希值除以一个数得到的余数就是对应数组的索引,有可能取得余数一样就搞一个链表)就好比设置除数是5要存10,20这两个数都可以存在索引为o的位置,但是不能一下子存两个就生成链表存
其中无符号右移16位然后做异或运算效率最高
2当两个对象的 hashCode 相等时会怎么样?
答:会产生哈希碰撞。若 key 值内容相同则替换旧的 value,不然连接到链表后面,链表长度超过阈值 8 且数组长度超过64就转换为红黑树存储。
3什么是哈希碰撞,如何解决哈希碰撞?
答:只要两个元素的 key 计算的哈希码值相同就会发生哈希碰撞。jdk8 之前使用链表解决哈希碰撞。jdk8之后使用链表 + 红黑树解决哈希碰撞。
4如果两个键的 hashCode 相同,如何存储键值对?
答:通过 equals 比较内容是否相同。相同:则新的 value 覆盖之前的 value。不相同:则将新的键值对添加到哈希表中。
5.初始长度16,加载因子0.75