HashMap底层实现原理

简介:

HashMap在java集合中的位置如图所示:
在这里插入图片描述
HashMap继承的是AbstractMap,而AbstractMap实现的是Map接口。
HashMap的存储方式是<key,value>键值对的形式,其中,key是唯一的,value可以重复。
基本使用方法:
put,get方法:

  		Map<String,Integer> m1 = new HashMap<>();
        Map<String,Integer> m2 = new HashMap<>();
        m1.put("AAA",1);
        m1.put("bbb",2);
        m2.put("ccc",3);
        System.out.println(m1.get("AAA"));
        System.out.println(m2.get("ccc"));

打印结果

1
3

实现原理

JDK8之前:数组+链表
JDK8之后:数组+链表+红黑树,红黑树的作用是提高查询效率
JDK8之后,如果哈希表单向链表中元素超过8个,那么单向链表这种数据结构会变成红黑树数据结构。当红黑树上的节点数量小于6个,会重新把红黑树变成单向链表数据结构。
在这里插入图片描述
底层源码:
在这里插入图片描述
可以看到源码里,put方法return的是putVal(hash(key), key, value, false, true)方法。
而继续查看putVal方法:
5个参数分别是:
hash:key的hash值
key:key值
value:key对应的value值
onlyIfAbsent:如果是true,则不改变已经存在的value值,反之改变
evict:如果为false,则表进入创建模式
在这里插入图片描述
在这里插入图片描述
首先,看628行,if判断数组tab是否为空或逻辑长度是否为0?是,就分配长度,一般为16。
630行,if判断p是否为null,p是什么?我们看到这么一句代码:

p = tab[i = (n - 1) & hash]

tab是数组,然后将(n-1)和key的hash值的&运算结果作为tab数组的下标。那么,p为数组中的某个位置或元素。如果p为空,那么说明这个位置没有k,v。那么可以新建一个Node节点(因为数组每个元素都是一个链表结构)。

如果上述两个if都不成立,即说明该位置已有元素了。再看632行else里的逻辑:

if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;

先if判断p位置的hash值是否等于要放入的Key的hash值并且(比较key是否==或者equal)?是的话那么将p赋值给e。
639else里:下标重复处理,关键一行代码:

p.next = newNode(hash, key, value, null);

也就是说new一个新的Node对象并把当前Node的next引用指向该对象,也就是说原来该位置上只有一个元素对象,现在转成了单向链表。
我们在上面说过,当链表长度到8时,则将链表转化为红黑树:

if (binCount >= TREEIFY_THRESHOLD - 1) //当binCount>=TREEIFY_THRESHOLD-1
      treeifyBin(tab, hash);//把链表转化为红黑树

而TREEIFY_THRESHOLD的值为:
HashMap.java 258行代码

 static final int TREEIFY_THRESHOLD = 8;

在Map中,一个key,对应了一个value,如果key的值已经存在,Map会直接替换value的内容,来看一下源码中是怎么实现的,来看以下代码
653行:

if (e != null) { // existing mapping for key
     V oldValue = e.value;//定义一个变量来存旧值
     if (!onlyIfAbsent || oldValue == null)
     e.value = value;//把value的值赋值为新的值
     afterNodeAccess(e);
     return oldValue;//返回的值
}

未完待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值