java hashmap put_HashMap详解(一). put方法详解

JAVA8

1.HashMap.put 方法实现了Map.put(K key,V value)的方法。直接调用内部方法

4974e359f3c76ba3e84d04065303b386.png

大致思路是这样的:

对key的hashCode()进行hash后计算数组下标index;

如果当前数组table为null,进行resize()初始化;

如果没碰撞直接放到对应下标的bucket里;

如果碰撞了,且节点已经存在,就替换掉 value;

如果碰撞后发现为树结构,挂载到树上。

如果碰撞后为链表,添加到链表尾,并判断链表如果过长(大于等于TREEIFY_THRESHOLD,默认8),就把链表转换成树结构;

数据 put 后,如果数据量超过threshold,就要resize。

下面是putVal方法解析

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,

boolean evict) {

Node[] tab; Node p; int n, i;

if ((tab = table) == null || (n = tab.length) == 0) //首次放入元素时,分配table空间-默认size=16

n = (tab = resize()).length;

if ((p = tab[i = (n - 1) & hash]) == null) // 算出新node在table中的位置,若对应位置为null,新建一个node并放入对应位置.

// 注意: (n - 1) & hash 求余操作 等价于 hash%n(只有n为2的幂时才成立,见下图)

tab[i] = newNode(hash, key, value, null);

else { //在table对应位置有node时

Node e; K k;

if (p.hash == hash && // key一样 (hash值相同,且key 一样,相同实例或者满足Object.equals方法)

((k = p.key) == key || (key != null && key.equals(k)))) // 不满足此条件则发生hash碰撞

e = p;

else if (p instanceof TreeNode) // hash碰撞的情况下,用链表解决,链表大于8时,改为红黑树. 当node为treeNode时,putTreeVal->红黑树

e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);

else { //hash

for (int binCount = 0; ; ++binCount) { //用for循环将链表指针后移,将新node在链表加在尾部

if ((e = p.next) == null) {

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

if (binCount >= TREEIFY_THRESHOLD - 1) // 当链表长度大于8时,转成红黑树

treeifyBin(tab, hash);

break;

}

if (e.hash == hash &&

((k = e.key) == key || (key != null && key.equals(k))))

break;

p = e;

}

}

if (e != null) { // existing mapping for key

V oldValue = e.value;

if (!onlyIfAbsent || oldValue == null) //当node中旧的值null或者onlyIfAbsent==false时,将新的value替换原来的value.

e.value = value;

afterNodeAccess(e); //新node塞入table后做的做的事情,在HashMap中是一个空方法(LinkedHashMap中有有使用, move node to last)

return oldValue;

}

}

++modCount;

if (++size > threshold) //新的size大于阈值(默认0.75*table.length)时,扩容.

resize();

afterNodeInsertion(evict);

return null;

}

ed1262fecb4fc89f4a4e1752d4b6b363.png

总结.

1.第一次put操作时,才为table分配内存空间,

2.当发生hash碰撞时,先链表,链表长度大于8时,转为红黑树.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值