HashMap集合中每个键值对也叫Entry,这些Entry分散的存储在一个数组中,这个数组是HashMap的主干,数组中每个元素初始值为null,HashMap的默认长度为16,或者手动设置为2的n次方(之所以是2^n,是为了配合从key映射到index的hash算法,使插入的数据能均匀分布在数组中,避免有些index结果的出现几率会更大,而有些index可能永远不会出现);
HashMap是怎么进行数据存取的;即HashMap常用的get和put方法原理;
put原理:如hashMap.put("apple", 0);在插入一个键为apple的时候,
通过HashCode(key)&(length-1)算法公式来判断这个Entry该插入数组中的哪个位置(index);
------HashCode(key)返回一个十进制的数值,转化为二进制后和HashMap长度进行与运算;
可以说,Hash算法最终得到的index结果,完全取决于key的HashCode值的最后几位;
由于哈希函数算法不可避免会计算出index相冲突的情况,解决这个问题:
--------HashMap数组的每一个元素不止是一个Entry对象,也是一个链表的头节点。每一个Entry对象通过Next指针指向它的下一个Entry节点。当新来的Entry映射到冲突的数组位置时,只需要插入到对应的链表即可(jdk1.8之前是用“头插法”);
get原理:
首先会把输入的Key做一次Hash映射,得到对应的index:index = Hash(“apple”)
对于出现index冲突的位置,可能会匹配多个Entry,此时就需要顺着对应的链表的头结点往下一个个查找;
在JDK1.8中对HashMap进行了改进(存储结构:数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的)
以上内容是对来自微信公众号:算法爱好者 中一篇文章的总结;
图片来源于ImportNew中“Java8系列之重新认识HashMap”