hashMap存取

 

一.Put方法

情况一:

 

  1. 点击上面put进入下面

   第一步:先取得hashCode值;

   第二步:根据hashCode值取得hash值;

   第三步:hash值取余得到一个下标i;

以上代码如下:

                          

结果如下:

   第四步:遍历下标位置的hash桶;

   第五步:如果引用相等或equals相等,做一个替换;

  2.点击上面hash进入下面

 

  3.下面map = null;打断点

 

  4.打完断点进入下面,发现key=”a10”,紧接着next下面key=”a0”,所以a10和a0储存在第【6】个位置。

 

一.Put

情况二:

1.

 

   2.上述点击put进入下面底层代码

 

上述u1=null,上面蓝色部分不执行;

如果值没存过,放到addEntry(hash,key,value,i)里面存,返回null;

如果值存过做if判断,hashCode值相等而且引用相等或者equals相等,值相等才能发生替换返回oldValue;

注意:点击上面e.recordAccess(this)进入下面:把旧的值放到新的value里面,把新的里面next引用去指向那个旧的值

 

注意:点击上上面addEntry(hash,key,value,i);进入下面,当size>=threshold时,求出hash值,下面2*table.length扩容两倍后重新求出索引。

 

点击上面createEntry(hash,key,value,bucketIndex)进入下面

 

 把e取出来(代表旧的),new新的构造方法的时候把旧的给传进去(里面key和value是新的),点击上面Entry方法进入下面

 

上面让next = n表示next引用去指向旧的,这样就形成一个链表(通过hash碰撞才能实现链表)

二.get方法

 

get是反过来操作一遍,根据key再求hash,根据hash再余运算获取hash桶的下标,hash值遍历不为空的值时,判断如果查到索引i(或者查到里面链表e.next,并且查到相应索引值和键值,则返回一个值,如下:

 

上面如果第一个元素key为null,直接取第一个元素,否则点击getEntry()方法把key传进去,判断size是否等于0,Entry()对象里面有next引用,next引用会指向另一个Entry()对象,所有用了for取遍历取出来的Entry,if判断hash值是否相等。

 

hashMap原理:

总结:1.HashMap底层是数组加链表,之所以用数组因为数组内存空间是连续的,用链表是因为插入和删除比较快的,只需要一个引用对象去指向另一个引用对象;

2.用map底层只需解释put方法,put一个新的k和value值的时候*(如果key为null放在hash表的第一个位置,如果不为null对key求hash,对key的值和hash表的长度做余运算去获取keyvalue键值对,hash位置有元素判断是否有hash碰撞,把旧的取出来,把新的放到旧的位置上,把新的应用对象里面的next去指向那个旧的oldvalue,这样形成一个列表关系),这个列表就形成了;至于怎么添加则要调用Entry方法,先去判断当前hash表的容量是否足以容纳当前要存放的这些元素,如果不足以容纳则要对hash表进行扩容2(n)(扩容效率,最大2(30))对keyhash重新去求hash ,重新获取hash表的下标,再调用ENtry方法,然后完成这个存储的过程;

    3.get方法是反过来操作一遍,根据key再求hash,根据hash再余运算获取hash桶的下标根据下标遍历求出对应Entry的链表,遍历出列表取出来想要的那个key。具体:如果第一个元素key为null,直接取第一个元素,否则点击getEntry()方法把key传进去,判断size是否等于0,Entry()对象里面有next引用,next引用会指向另一个Entry()对象,所有用了for取遍历取出来的Entry,if判断hash值是否相等。

 

 

hashMap与HashTable的区别:

  1. map线程不安全;初始化容量16;键值对可以为;性能高;位运算符;最大扩容2(30);
  2. table线程安全;初始化容量11;键值对不能为空;

猜你喜欢

转载自www.cnblogs.com/wlg-gg/p/9563895.html