HashMap的相关

77 阅读2分钟

1.put方法!

1.key经过哈希算法得到一个下标

如果改位置没有元素

将key和value封装为一个 1.8node或者是1.7entiy

如果该位置有元素
1.7判断是否需要扩容

  需要扩容就扩容

  不需要扩容就头插法插入链表
1.8判断改位置的元素是链表node还是红黑树node

  链表node,将key和value封装为node,然后尾插法插入链表,尾插法需要遍历链表,如果key存在,直接更新value 插入后如果链表长度大于等于阈值,就链表转化为红黑树

    判断是否需要扩容

  红黑树node,将key value插入红黑树,如果key存在就更新value,

    判断是否需要扩容

2.扩容机制

hashmap的扩容机制,两种情况。

1.有数据的节点数量达到负载因子后,就发生扩容。

2.数组长度<64,链表长度达到8的时候,发生扩容

树化:当数组长度达到64时,链表长度达到8,就链表转化为红黑树。长度<8时,又会转化成链表

3.为什么Hashmap线程不安全

  1. 1.7的时候,hashmap使用头插法,并发扩容情况下会造成死链

     如何扩容?
     线程
     为什么造成死链?
     多线程同时扩容,由于1.7是头插法,扩容后,链表顺序会发生反转,
     当一个线程完成了扩容(A->B->C->null)->(C->B->A->null),
     另一个线程如果在第一个线程扩容前准备扩容但时间片用完了,在第一
     个线程扩容后再次获得时间片,线程2此时的指向为T2->A,T2.next->B(A->B) 
     此时就发生了死链()。
    
  2. 多线程同时执行 put 操作时,如果计算出来的索引位置是相同的,那会造成前一个 key 被后一个 key 覆盖,从而导致元素的丢失。