Java并发 - J.U.C并发容器类Map - HashMap的扩展知识

基于前面的Java并发 - J.U.C并发容器类Map - HashMap简单分析,我们接着来对HashMap的相关知识进行一个补充。

HashMap插入数据的思路

  • HashMap插入数据的思路
  1. 对应的数组下标的元素为空,直接放
  2. key 是不是同一个key,如果是则进行value的替换
  3. key 不是同一个,且数组有元素,则判断是链表还是树
    • 是链表:判断是否达到了树的要求,没达到就挂链表,否则变成红黑树
    • 是红黑树:挂到红黑树后边的节点中去

链表长度==8 的时候,会自动转换成红黑树

    /**
     * The bin count threshold for using a tree rather than list for a
     * bin.  Bins are converted to trees when adding an element to a
     * bin with at least this many nodes. The value must be greater
     * than 2 and should be at least 8 to mesh with assumptions in
     * tree removal about conversion back to plain bins upon
     * shrinkage.
     */
    static final int TREEIFY_THRESHOLD = 8;

但是即便如此,就算加入了红黑树,如果数组长度一定的情况下,大量数据放入map中,发生hash碰撞的几率就越大,那么红黑树必然也会越来越庞大,照样会影响查询的效率。本质来说,这是数组的长度限制导致的,所以数组的扩容很是必要。


HashMap的扩容

  • 数组的扩容:当数组满足空间被占用的75%的时候(默认的填充因子是0.75f),会进行扩容,数组容量和填充因子都向左平移1位 << 1 即呈2倍扩容。
    此时会进行创建新的数组,然后再对旧的数组及挂在在元素下的链表(或红黑树)进行迁移。
    迁移的情況:
  1. 遍历老数组,如果有元素且只有一个元素,那么直接进行迁移
  2. 数组的元素下是一个链表,那么就遍历链表,取模然后插入新的数组
  3. 数组的元素下是一个红黑树,那么就打散树之后再遍历树的元素,取模然后插入新的数组中

HashMap的总结

这部分在Java并发 - J.U.C并发容器类Map - HashMap简单分析 也有描述:

  • HashMap是数组+链表构成的,JDK1.8之后,加入了红黑树.
  • HashMap默认数组初始化大小为16,如果瞎设置数字,它会自动调整成 2 的倍数.
  • HashMap链表在长度为 8 之后,会自动转换成红黑树,数组扩容之后,会打散红黑树,重新设置.
  • HashMap扩容变化因子是0.75,也就是数组的3/4被占用之后,开始扩容。
  • 在第一次调用PUT方法之前,HashMap是没有数组也没有链表的,在每次put元素之后,开始检查(生成)数组和链表.

与HashTable的比较

大体是一致的,只是暴露的方法里边多了 synchronized 修饰符,确保了线程安全,但是不推荐使用,主要是在多线程调用的时候,一个同步的修饰符会导致性能下降,与Map设计的初衷提升访问速度相违背。所以对于HashTable只要知道它线程安全的原因是加入了synchronized修饰符

  • get 方法中加入了synchronized修饰符
    public synchronized V get(Object key) {
        Entry tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return (V)e.value;
            }
        }
        return null;
    }

如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~

你可能感兴趣的:(Java并发 - J.U.C并发容器类Map - HashMap的扩展知识)