1.1哈希算法定义
对某个元素进行哈希运算,把一个较长的二进值映射为较短的固定长度的二进制值,这个小的二进制值就是哈希值,是一个存储地址,然后根据地址进行元素的存储操作。具体映射方法采用位运算。(不用取模,因为第一,如果是负数,需要便为正数;第二效率较慢)。JDK1.7 的HashMap底层采用:数组(数组的查询元素的效率为O(1))+链表。数组的默认存储空间为16(2^n)。为什么是2^n,因为只有是2^1,进行减1操作,才能拿到全是1的二进制数值,在进行按位与,才能快速运用位运算的方式拿到数组的下标,并且分布均匀)。
1.2哈希碰撞定义
通过哈希运算找到元素存储地址,进行插入,发现已经被其他元素占用了,这就是哈希冲突,也是哈希碰撞。
1.3解决哈希碰撞的方式
1.3.1线性探测法
主要根据index=val.hashcode()%element.length来解决哈希冲突问题。从数组当前hashCode的位置开始,找到下一个空位置进行存储。当数组填充满之后,进行数组的扩容操作。继续存放值。存储的键值对键相同值进行覆盖操作。进行扩容后的操作,还需要进行元素的重新哈希操作。
1.3.2链地址法
线性探测法当产生哈希冲突的键值对越多,遍历数组的次数就越多。采用数组+链表结合的方法,数组元素是一个链表结构。产生哈希冲突,在相同的索引下标下进行链表的插入操作。
不足:
(1)当产生哈希冲突的节点越多,数组索引下标查找就会变成链表的遍历操作,数组的优势在于随机取值,时间复杂度为O(1),而链表的时间复杂度为O(n)。
(2)当产生数组扩容时,所有的元素节点都必须重新哈希。